From ab0a10105c7f44f6743b93ea21c32348d34bd4bd Mon Sep 17 00:00:00 2001 From: Astronand Date: Thu, 26 Mar 2026 08:12:37 -0400 Subject: [PATCH 1/6] formating better for spm packages --- Src/Hyperion-core/{ => data}/lib/colors | 0 Src/Hyperion-core/{ => data}/lib/fs | 0 Src/Hyperion-core/{ => data}/lib/http | 0 Src/Hyperion-core/{ => data}/lib/io | 0 .../{ => data}/boot/ac/boot.lua | 6 +- .../{ => data}/boot/ccpc/boot.lua | 0 .../{ => data}/boot/ccpc/eeprom | 0 .../{ => data}/boot/ccpc/initdisks | 0 .../{ => data}/lib/modules/ccpc/25_gfx.kmod | 0 .../{ => data}/boot/cct/boot.lua | 114 +- .../{ => data}/boot/cct/eeprom | 0 .../{ => data}/boot/cct/initdisks | 0 .../lib/modules/cc-tweaked/01_periph.kmod | 0 .../data/lib/modules/cc-tweaked/22_http.kmod | 1 + .../lib/modules/cc-tweaked/25_tty.kmod | 2 - .../lib/modules/cc-tweaked/30_deamon.kmod | 0 .../lib/modules/cc-tweaked/51_gpio.kmod | 0 .../{ => data}/boot/oc/boot.lua | 0 .../{ => data}/boot/oc/eeprom | 0 .../{ => data}/boot/oc/initfs.lua | 0 Src/Hyperion-kernel/{ => data}/boot/fstab | 0 Src/Hyperion-kernel/{ => data}/boot/initfs | 0 .../{ => data}/boot/kernel.lua | 24 +- .../{ => data}/boot/safeboot.cfg | 3 +- Src/Hyperion-kernel/{ => data}/etc/passwd | 0 Src/Hyperion-kernel/{ => data}/etc/shadow | 0 .../lib/modules/hyperion/01_stdlib.kmod | 0 .../lib/modules/hyperion/10_vfs.kmod | 37 +- .../lib/modules/hyperion/11_require.kmod | 0 .../lib/modules/hyperion/12_devfs.kmod | 2 +- .../lib/modules/hyperion/12_procfs.kmod | 0 .../lib/modules/hyperion/12_tmpfs.kmod | 0 .../lib/modules/hyperion/13_loopdev.kmod | 0 .../lib/modules/hyperion/19_fstab.kmod | 0 .../lib/modules/hyperion/20_signals.kmod | 0 .../lib/modules/hyperion/20_socket.kmod | 23 +- .../lib/modules/hyperion/21_unixsockets.kmod | 4 + .../lib/modules/hyperion/30_userspace.kmod | 0 .../lib/modules/hyperion/40_auth.kmod | 0 .../lib/modules/hyperion/45_hypervisor.kmod | 38 +- .../lib/modules/hyperion/47_dbg.kmod | 0 .../lib/modules/hyperion/50_gpio.kmod | 0 .../lib/modules/hyperion/70_stdlibadv.kmod | 0 .../lib/modules/hyperion/90_init.kmod | 0 .../lib/modules/hyperion/91_login.kmod | 0 .../lib/modules/hyperion/92_setup.kmod | 0 .../lib/modules/hyperion/99_final.kmod | 0 .../lib/modules/hyperion/21_unixsockets.kmod | 3 - Src/bit32/{ => data}/lib/bit32 | 0 Src/blake2s/{ => data}/lib/crypto/blake2s | 0 Src/deflate/{ => data}/lib/LibDeflate | 0 Src/deflate/{ => data}/lib/deflate | 0 Src/hysh/{ => data}/bin/chattr | 0 Src/hysh/{ => data}/bin/chgrp | 0 Src/hysh/{ => data}/bin/chmod | 0 Src/hysh/{ => data}/bin/chown | 0 Src/hysh/{ => data}/bin/chroot | 0 Src/hysh/{ => data}/bin/help | 0 Src/hysh/{ => data}/bin/hfetch | 0 Src/hysh/{ => data}/bin/hysh | 9 +- Src/hysh/{ => data}/bin/id | 0 Src/hysh/{ => data}/bin/ll | 0 Src/hysh/{ => data}/bin/ln | 0 Src/hysh/{ => data}/bin/login | 0 Src/hysh/{ => data}/bin/loimgcreate | 0 Src/hysh/{ => data}/bin/losetup | 0 Src/hysh/{ => data}/bin/ls | 2 + Src/hysh/{ => data}/bin/lsusers | 0 Src/hysh/{ => data}/bin/mount | 0 Src/hysh/{ => data}/bin/passwd | 0 Src/hysh/{ => data}/bin/ps | 0 Src/hysh/{ => data}/bin/readlink | 0 Src/{sed => hysh/data}/bin/sed | 0 Src/hysh/{ => data}/bin/su | 0 Src/hysh/{ => data}/bin/sudo | 0 Src/hysh/{ => data}/bin/sysdump | 0 Src/hysh/{ => data}/bin/umount | 0 Src/hysh/{ => data}/bin/useradd | 0 Src/hysh/{ => data}/bin/userdel | 0 Src/hysh/{ => data}/bin/usermod | 0 Src/hysh/{ => data}/bin/yes | 0 Src/iniparse/{ => data}/lib/iniparse | 0 Src/install.json | 6 +- Src/json/{ => data}/lib/json | 0 Src/lua/{ => data}/bin/lua | 1 + Src/micro/{ => data}/bin/micro | 0 Src/spm/{ => data}/bin/spm | 0 Src/sysinit/$PKGCONFIG.ini | 1 - Src/sysinit/{ => data}/sbin/init | 0 .../{ => data}/usr/lib/sysinit/sysinit | 0 Src/xz/data/lib/xz | 1973 +++++++++++++++++ build.py | 15 +- installers/HyperionOS-install-cct.lua | 14 +- misc/spm.lua | 55 + misc/xz | 1973 +++++++++++++++++ .../Hyperion-core.pkg | 0 .../Hyperion-firmware-cct.pkg | 0 .../Hyperion-kernel.pkg | 0 .../etc/shadow => packages/HyperionOS.pkg | 0 packages/spm.pkg | 14 + prod/Hyperion-core/lib/colors | 1 - prod/Hyperion-core/lib/fs | 1 - prod/Hyperion-core/lib/io | 6 - prod/Hyperion-firmware-ac/boot/ac/boot.lua | 1 - .../Hyperion-firmware-ccpc/boot/ccpc/boot.lua | 1 - prod/Hyperion-firmware-ccpc/boot/ccpc/eeprom | 1 - .../boot/ccpc/initdisks | 1 - .../lib/modules/ccpc/25_gfx.kmod | 1 - prod/Hyperion-firmware-cct/boot/cct/boot.lua | 1 - prod/Hyperion-firmware-cct/boot/cct/eeprom | 1 - prod/Hyperion-firmware-cct/boot/cct/initdisks | 1 - .../lib/modules/cc-tweaked/01_periph.kmod | 1 - .../lib/modules/cc-tweaked/25_tty.kmod | 1 - .../lib/modules/cc-tweaked/30_deamon.kmod | 1 - .../lib/modules/cc-tweaked/51_gpio.kmod | 1 - prod/Hyperion-firmware-oc/boot/oc/boot.lua | 41 - prod/Hyperion-firmware-oc/boot/oc/eeprom | 18 - prod/Hyperion-firmware-oc/boot/oc/initfs.lua | 1 - prod/Hyperion-kernel/boot/fstab | 4 - prod/Hyperion-kernel/boot/initfs | 84 - prod/Hyperion-kernel/boot/kernel.lua | 1 - prod/Hyperion-kernel/boot/safeboot.cfg | 12 - prod/Hyperion-kernel/etc/passwd | 1 - .../lib/modules/hyperion/01_stdlib.kmod | 1 - .../lib/modules/hyperion/10_vfs.kmod | 1 - .../lib/modules/hyperion/11_require.kmod | 1 - .../lib/modules/hyperion/12_devfs.kmod | 1 - .../lib/modules/hyperion/12_procfs.kmod | 1 - .../lib/modules/hyperion/12_tmpfs.kmod | 1 - .../lib/modules/hyperion/13_loopdev.kmod | 1 - .../lib/modules/hyperion/19_fstab.kmod | 1 - .../lib/modules/hyperion/20_signals.kmod | 1 - .../lib/modules/hyperion/20_socket.kmod | 1 - .../lib/modules/hyperion/21_unixsockets.kmod | 1 - .../lib/modules/hyperion/30_userspace.kmod | 1 - .../lib/modules/hyperion/40_auth.kmod | 1 - .../lib/modules/hyperion/45_hypervisor.kmod | 1 - .../lib/modules/hyperion/47_dbg.kmod | 1 - .../lib/modules/hyperion/50_gpio.kmod | 1 - .../lib/modules/hyperion/70_stdlibadv.kmod | 1 - .../lib/modules/hyperion/90_init.kmod | 1 - .../lib/modules/hyperion/91_login.kmod | 1 - .../lib/modules/hyperion/92_setup.kmod | 1 - .../lib/modules/hyperion/99_final.kmod | 1 - prod/bit32/lib/bit32 | 1 - prod/blake2s/lib/crypto/blake2s | 1 - prod/deflate/lib/LibDeflate | 1 - prod/deflate/lib/deflate | 9 - prod/hysh/bin/chattr | 1 - prod/hysh/bin/chgrp | 1 - prod/hysh/bin/chmod | 1 - prod/hysh/bin/chown | 1 - prod/hysh/bin/chroot | 1 - prod/hysh/bin/help | 1 - prod/hysh/bin/hfetch | 1 - prod/hysh/bin/hysh | 1 - prod/hysh/bin/id | 1 - prod/hysh/bin/ll | 3 - prod/hysh/bin/ln | 1 - prod/hysh/bin/login | 1 - prod/hysh/bin/loimgcreate | 1 - prod/hysh/bin/losetup | 1 - prod/hysh/bin/ls | 1 - prod/hysh/bin/lsusers | 1 - prod/hysh/bin/mount | 1 - prod/hysh/bin/passwd | 1 - prod/hysh/bin/ps | 1 - prod/hysh/bin/readlink | 1 - prod/hysh/bin/su | 1 - prod/hysh/bin/sudo | 1 - prod/hysh/bin/sysdump | 1 - prod/hysh/bin/umount | 1 - prod/hysh/bin/useradd | 1 - prod/hysh/bin/userdel | 1 - prod/hysh/bin/usermod | 1 - prod/hysh/bin/yes | 1 - prod/iniparse/lib/iniparse | 1 - prod/json/lib/json | 1 - prod/lua/bin/lua | 1 - prod/micro/bin/micro | 1 - prod/sed/bin/sed | 1 - prod/spm/bin/spm | 6 - prod/sysinit/sbin/init | 4 - prod/sysinit/usr/lib/sysinit/sysinit | 1 - spm.json | 28 + spm/pkg/HyperionOS-bash.pkg | 10 - spm/pkg/HyperionOS-core.pkg | 10 - spm/pkg/HyperionOS-firmware-cct.pkg | 10 - spm/pkg/HyperionOS-firmware-oc.pkg | 10 - spm/pkg/HyperionOS-kernel.pkg | 10 - spm/pkg/HyperionOS-units.pkg | 10 - spm/pkg/HyperionOS.pkg | 10 - spm/spm.src | 13 - 193 files changed, 4228 insertions(+), 464 deletions(-) rename Src/Hyperion-core/{ => data}/lib/colors (100%) rename Src/Hyperion-core/{ => data}/lib/fs (100%) rename Src/Hyperion-core/{ => data}/lib/http (100%) rename Src/Hyperion-core/{ => data}/lib/io (100%) rename Src/Hyperion-firmware-ac/{ => data}/boot/ac/boot.lua (98%) rename Src/Hyperion-firmware-ccpc/{ => data}/boot/ccpc/boot.lua (100%) rename Src/Hyperion-firmware-ccpc/{ => data}/boot/ccpc/eeprom (100%) rename Src/Hyperion-firmware-ccpc/{ => data}/boot/ccpc/initdisks (100%) rename Src/Hyperion-firmware-ccpc/{ => data}/lib/modules/ccpc/25_gfx.kmod (100%) rename Src/Hyperion-firmware-cct/{ => data}/boot/cct/boot.lua (86%) rename Src/Hyperion-firmware-cct/{ => data}/boot/cct/eeprom (100%) rename Src/Hyperion-firmware-cct/{ => data}/boot/cct/initdisks (100%) rename Src/Hyperion-firmware-cct/{ => data}/lib/modules/cc-tweaked/01_periph.kmod (100%) create mode 100644 Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod rename Src/Hyperion-firmware-cct/{ => data}/lib/modules/cc-tweaked/25_tty.kmod (99%) rename Src/Hyperion-firmware-cct/{ => data}/lib/modules/cc-tweaked/30_deamon.kmod (100%) rename Src/Hyperion-firmware-cct/{ => data}/lib/modules/cc-tweaked/51_gpio.kmod (100%) rename Src/Hyperion-firmware-oc/{ => data}/boot/oc/boot.lua (100%) rename Src/Hyperion-firmware-oc/{ => data}/boot/oc/eeprom (100%) rename Src/Hyperion-firmware-oc/{ => data}/boot/oc/initfs.lua (100%) rename Src/Hyperion-kernel/{ => data}/boot/fstab (100%) rename Src/Hyperion-kernel/{ => data}/boot/initfs (100%) rename Src/Hyperion-kernel/{ => data}/boot/kernel.lua (93%) rename Src/Hyperion-kernel/{ => data}/boot/safeboot.cfg (88%) rename Src/Hyperion-kernel/{ => data}/etc/passwd (100%) rename Src/Hyperion-kernel/{ => data}/etc/shadow (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/01_stdlib.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/10_vfs.kmod (97%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/11_require.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/12_devfs.kmod (99%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/12_procfs.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/12_tmpfs.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/13_loopdev.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/19_fstab.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/20_signals.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/20_socket.kmod (77%) create mode 100644 Src/Hyperion-kernel/data/lib/modules/hyperion/21_unixsockets.kmod rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/30_userspace.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/40_auth.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/45_hypervisor.kmod (93%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/47_dbg.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/50_gpio.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/70_stdlibadv.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/90_init.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/91_login.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/92_setup.kmod (100%) rename Src/Hyperion-kernel/{ => data}/lib/modules/hyperion/99_final.kmod (100%) delete mode 100644 Src/Hyperion-kernel/lib/modules/hyperion/21_unixsockets.kmod rename Src/bit32/{ => data}/lib/bit32 (100%) rename Src/blake2s/{ => data}/lib/crypto/blake2s (100%) rename Src/deflate/{ => data}/lib/LibDeflate (100%) rename Src/deflate/{ => data}/lib/deflate (100%) rename Src/hysh/{ => data}/bin/chattr (100%) rename Src/hysh/{ => data}/bin/chgrp (100%) rename Src/hysh/{ => data}/bin/chmod (100%) rename Src/hysh/{ => data}/bin/chown (100%) rename Src/hysh/{ => data}/bin/chroot (100%) rename Src/hysh/{ => data}/bin/help (100%) rename Src/hysh/{ => data}/bin/hfetch (100%) rename Src/hysh/{ => data}/bin/hysh (99%) rename Src/hysh/{ => data}/bin/id (100%) rename Src/hysh/{ => data}/bin/ll (100%) rename Src/hysh/{ => data}/bin/ln (100%) rename Src/hysh/{ => data}/bin/login (100%) rename Src/hysh/{ => data}/bin/loimgcreate (100%) rename Src/hysh/{ => data}/bin/losetup (100%) rename Src/hysh/{ => data}/bin/ls (99%) rename Src/hysh/{ => data}/bin/lsusers (100%) rename Src/hysh/{ => data}/bin/mount (100%) rename Src/hysh/{ => data}/bin/passwd (100%) rename Src/hysh/{ => data}/bin/ps (100%) rename Src/hysh/{ => data}/bin/readlink (100%) rename Src/{sed => hysh/data}/bin/sed (100%) rename Src/hysh/{ => data}/bin/su (100%) rename Src/hysh/{ => data}/bin/sudo (100%) rename Src/hysh/{ => data}/bin/sysdump (100%) rename Src/hysh/{ => data}/bin/umount (100%) rename Src/hysh/{ => data}/bin/useradd (100%) rename Src/hysh/{ => data}/bin/userdel (100%) rename Src/hysh/{ => data}/bin/usermod (100%) rename Src/hysh/{ => data}/bin/yes (100%) rename Src/iniparse/{ => data}/lib/iniparse (100%) rename Src/json/{ => data}/lib/json (100%) rename Src/lua/{ => data}/bin/lua (99%) rename Src/micro/{ => data}/bin/micro (100%) rename Src/spm/{ => data}/bin/spm (100%) delete mode 100644 Src/sysinit/$PKGCONFIG.ini rename Src/sysinit/{ => data}/sbin/init (100%) rename Src/sysinit/{ => data}/usr/lib/sysinit/sysinit (100%) create mode 100644 Src/xz/data/lib/xz create mode 100644 misc/spm.lua create mode 100644 misc/xz rename Src/Hyperion-firmware-cct/lib/modules/cc-tweaked/22_http.kmod => packages/Hyperion-core.pkg (100%) rename prod/Hyperion-core/lib/http => packages/Hyperion-firmware-cct.pkg (100%) rename prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/22_http.kmod => packages/Hyperion-kernel.pkg (100%) rename prod/Hyperion-kernel/etc/shadow => packages/HyperionOS.pkg (100%) create mode 100644 packages/spm.pkg delete mode 100644 prod/Hyperion-core/lib/colors delete mode 100644 prod/Hyperion-core/lib/fs delete mode 100644 prod/Hyperion-core/lib/io delete mode 100644 prod/Hyperion-firmware-ac/boot/ac/boot.lua delete mode 100644 prod/Hyperion-firmware-ccpc/boot/ccpc/boot.lua delete mode 100644 prod/Hyperion-firmware-ccpc/boot/ccpc/eeprom delete mode 100644 prod/Hyperion-firmware-ccpc/boot/ccpc/initdisks delete mode 100644 prod/Hyperion-firmware-ccpc/lib/modules/ccpc/25_gfx.kmod delete mode 100644 prod/Hyperion-firmware-cct/boot/cct/boot.lua delete mode 100644 prod/Hyperion-firmware-cct/boot/cct/eeprom delete mode 100644 prod/Hyperion-firmware-cct/boot/cct/initdisks delete mode 100644 prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/01_periph.kmod delete mode 100644 prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/25_tty.kmod delete mode 100644 prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/30_deamon.kmod delete mode 100644 prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/51_gpio.kmod delete mode 100644 prod/Hyperion-firmware-oc/boot/oc/boot.lua delete mode 100644 prod/Hyperion-firmware-oc/boot/oc/eeprom delete mode 100644 prod/Hyperion-firmware-oc/boot/oc/initfs.lua delete mode 100644 prod/Hyperion-kernel/boot/fstab delete mode 100644 prod/Hyperion-kernel/boot/initfs delete mode 100644 prod/Hyperion-kernel/boot/kernel.lua delete mode 100644 prod/Hyperion-kernel/boot/safeboot.cfg delete mode 100644 prod/Hyperion-kernel/etc/passwd delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/01_stdlib.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/10_vfs.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/11_require.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/12_devfs.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/12_procfs.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/12_tmpfs.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/13_loopdev.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/19_fstab.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/20_signals.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/20_socket.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/21_unixsockets.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/30_userspace.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/40_auth.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/45_hypervisor.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/47_dbg.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/50_gpio.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/70_stdlibadv.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/90_init.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/91_login.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/92_setup.kmod delete mode 100644 prod/Hyperion-kernel/lib/modules/hyperion/99_final.kmod delete mode 100644 prod/bit32/lib/bit32 delete mode 100644 prod/blake2s/lib/crypto/blake2s delete mode 100644 prod/deflate/lib/LibDeflate delete mode 100644 prod/deflate/lib/deflate delete mode 100644 prod/hysh/bin/chattr delete mode 100644 prod/hysh/bin/chgrp delete mode 100644 prod/hysh/bin/chmod delete mode 100644 prod/hysh/bin/chown delete mode 100644 prod/hysh/bin/chroot delete mode 100644 prod/hysh/bin/help delete mode 100644 prod/hysh/bin/hfetch delete mode 100644 prod/hysh/bin/hysh delete mode 100644 prod/hysh/bin/id delete mode 100644 prod/hysh/bin/ll delete mode 100644 prod/hysh/bin/ln delete mode 100644 prod/hysh/bin/login delete mode 100644 prod/hysh/bin/loimgcreate delete mode 100644 prod/hysh/bin/losetup delete mode 100644 prod/hysh/bin/ls delete mode 100644 prod/hysh/bin/lsusers delete mode 100644 prod/hysh/bin/mount delete mode 100644 prod/hysh/bin/passwd delete mode 100644 prod/hysh/bin/ps delete mode 100644 prod/hysh/bin/readlink delete mode 100644 prod/hysh/bin/su delete mode 100644 prod/hysh/bin/sudo delete mode 100644 prod/hysh/bin/sysdump delete mode 100644 prod/hysh/bin/umount delete mode 100644 prod/hysh/bin/useradd delete mode 100644 prod/hysh/bin/userdel delete mode 100644 prod/hysh/bin/usermod delete mode 100644 prod/hysh/bin/yes delete mode 100644 prod/iniparse/lib/iniparse delete mode 100644 prod/json/lib/json delete mode 100644 prod/lua/bin/lua delete mode 100644 prod/micro/bin/micro delete mode 100644 prod/sed/bin/sed delete mode 100644 prod/spm/bin/spm delete mode 100644 prod/sysinit/sbin/init delete mode 100644 prod/sysinit/usr/lib/sysinit/sysinit create mode 100644 spm.json delete mode 100644 spm/pkg/HyperionOS-bash.pkg delete mode 100644 spm/pkg/HyperionOS-core.pkg delete mode 100644 spm/pkg/HyperionOS-firmware-cct.pkg delete mode 100644 spm/pkg/HyperionOS-firmware-oc.pkg delete mode 100644 spm/pkg/HyperionOS-kernel.pkg delete mode 100644 spm/pkg/HyperionOS-units.pkg delete mode 100644 spm/pkg/HyperionOS.pkg delete mode 100644 spm/spm.src diff --git a/Src/Hyperion-core/lib/colors b/Src/Hyperion-core/data/lib/colors similarity index 100% rename from Src/Hyperion-core/lib/colors rename to Src/Hyperion-core/data/lib/colors diff --git a/Src/Hyperion-core/lib/fs b/Src/Hyperion-core/data/lib/fs similarity index 100% rename from Src/Hyperion-core/lib/fs rename to Src/Hyperion-core/data/lib/fs diff --git a/Src/Hyperion-core/lib/http b/Src/Hyperion-core/data/lib/http similarity index 100% rename from Src/Hyperion-core/lib/http rename to Src/Hyperion-core/data/lib/http diff --git a/Src/Hyperion-core/lib/io b/Src/Hyperion-core/data/lib/io similarity index 100% rename from Src/Hyperion-core/lib/io rename to Src/Hyperion-core/data/lib/io diff --git a/Src/Hyperion-firmware-ac/boot/ac/boot.lua b/Src/Hyperion-firmware-ac/data/boot/ac/boot.lua similarity index 98% rename from Src/Hyperion-firmware-ac/boot/ac/boot.lua rename to Src/Hyperion-firmware-ac/data/boot/ac/boot.lua index 5b42647..a20abf1 100644 --- a/Src/Hyperion-firmware-ac/boot/ac/boot.lua +++ b/Src/Hyperion-firmware-ac/data/boot/ac/boot.lua @@ -106,7 +106,7 @@ local ok, err = xpcall(function() local file = {} - function file:read(n) + function file.read(n) assert(not closed, "file is closed") local s = content() @@ -123,7 +123,7 @@ local ok, err = xpcall(function() return out end - function file:write(data) + function file.write(data) assert(not closed, "file is closed") local s = content() @@ -136,7 +136,7 @@ local ok, err = xpcall(function() return true end - function file:seek(whence, offset) + function file.seek(whence, offset) assert(not closed, "file is closed") local s = content() diff --git a/Src/Hyperion-firmware-ccpc/boot/ccpc/boot.lua b/Src/Hyperion-firmware-ccpc/data/boot/ccpc/boot.lua similarity index 100% rename from Src/Hyperion-firmware-ccpc/boot/ccpc/boot.lua rename to Src/Hyperion-firmware-ccpc/data/boot/ccpc/boot.lua diff --git a/Src/Hyperion-firmware-ccpc/boot/ccpc/eeprom b/Src/Hyperion-firmware-ccpc/data/boot/ccpc/eeprom similarity index 100% rename from Src/Hyperion-firmware-ccpc/boot/ccpc/eeprom rename to Src/Hyperion-firmware-ccpc/data/boot/ccpc/eeprom diff --git a/Src/Hyperion-firmware-ccpc/boot/ccpc/initdisks b/Src/Hyperion-firmware-ccpc/data/boot/ccpc/initdisks similarity index 100% rename from Src/Hyperion-firmware-ccpc/boot/ccpc/initdisks rename to Src/Hyperion-firmware-ccpc/data/boot/ccpc/initdisks diff --git a/Src/Hyperion-firmware-ccpc/lib/modules/ccpc/25_gfx.kmod b/Src/Hyperion-firmware-ccpc/data/lib/modules/ccpc/25_gfx.kmod similarity index 100% rename from Src/Hyperion-firmware-ccpc/lib/modules/ccpc/25_gfx.kmod rename to Src/Hyperion-firmware-ccpc/data/lib/modules/ccpc/25_gfx.kmod diff --git a/Src/Hyperion-firmware-cct/boot/cct/boot.lua b/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua similarity index 86% rename from Src/Hyperion-firmware-cct/boot/cct/boot.lua rename to Src/Hyperion-firmware-cct/data/boot/cct/boot.lua index 0658ff3..6d9ff92 100644 --- a/Src/Hyperion-firmware-cct/boot/cct/boot.lua +++ b/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua @@ -1,9 +1,8 @@ --:Minify:-- local BOOT_DRIVE_PATH = ({...})[1] or "/$" ---@diagnostic disable-next-line: undefined-global -local term = term -local os = os -local function write(text) +local lterm = term +local function write(text, term) local x, y = term.getCursorPos() local w, h = term.getSize() @@ -49,13 +48,13 @@ local function write(text) end local function displaySuperBadError(err) - term.setBackgroundColor(0x1) - term.setTextColor(0x4) - term.clear() - term.setCursorPos(1, 1) - term.write("A critical error occurred while loading the system:") - term.setCursorPos(1, 3) - write(err) + lterm.setBackgroundColor(0x1) + lterm.setTextColor(0x4) + lterm.clear() + lterm.setCursorPos(1, 1) + lterm.write("A critical error occurred while loading the system:") + lterm.setCursorPos(1, 3) + write(err, lterm) while true do end end @@ -117,18 +116,18 @@ local ok, err = xpcall(function() while stoptime > apis.os.clock() do end end - apis.term.setPaletteColor(0x1, 0xFFFFFF) -- #000000 - apis.term.setPaletteColor(0x2, 0xFF0000) -- #FFFFFF - apis.term.setPaletteColor(0x4, 0x00FF00) -- #FF0000 - apis.term.setPaletteColor(0x8, 0x0000FF) -- #00FF00 - apis.term.setPaletteColor(0x10, 0x00FFFF) -- #0000FF - apis.term.setPaletteColor(0x20, 0xFF00FF) -- #00FFFF - apis.term.setPaletteColor(0x40, 0xFFFF00) -- #FF00FF - apis.term.setPaletteColor(0x80, 0xFF6D00) -- #FFFF00 - apis.term.setPaletteColor(0x100, 0x6DFF55) -- #FF6D00 - apis.term.setPaletteColor(0x200, 0x24FFFF) -- #6DFF55 - apis.term.setPaletteColor(0x400, 0x924900) -- #24FFFF - apis.term.setPaletteColor(0x800, 0x6D6D55) -- #924900 + apis.term.setPaletteColor(0x1, 0xFFFFFF) -- #000000 + apis.term.setPaletteColor(0x2, 0xFF0000) -- #FFFFFF + apis.term.setPaletteColor(0x4, 0x00FF00) -- #FF0000 + apis.term.setPaletteColor(0x8, 0x0000FF) -- #00FF00 + apis.term.setPaletteColor(0x10, 0x00FFFF) -- #0000FF + apis.term.setPaletteColor(0x20, 0xFF00FF) -- #00FFFF + apis.term.setPaletteColor(0x40, 0xFFFF00) -- #FF00FF + apis.term.setPaletteColor(0x80, 0xFF6D00) -- #FFFF00 + apis.term.setPaletteColor(0x100, 0x6DFF55) -- #FF6D00 + apis.term.setPaletteColor(0x200, 0x24FFFF) -- #6DFF55 + apis.term.setPaletteColor(0x400, 0x924900) -- #24FFFF + apis.term.setPaletteColor(0x800, 0x6D6D55) -- #924900 apis.term.setPaletteColor(0x1000, 0xDBDBAA) -- #6D6D55 apis.term.setPaletteColor(0x2000, 0x6D00FF) -- #DBDBAA apis.term.setPaletteColor(0x4000, 0xB6FF00) -- #6D00FF @@ -172,22 +171,22 @@ local ok, err = xpcall(function() end local colors = { - [0x000000]=0x0001, - [0xFFFFFF]=0x0002, - [0xFF0000]=0x0004, - [0x00FF00]=0x0008, - [0x0000FF]=0x0010, - [0x00FFFF]=0x0020, - [0xFF00FF]=0x0040, - [0xFFFF00]=0x0080, - [0xFF6D00]=0x0100, - [0x6DFF55]=0x0200, - [0x24FFFF]=0x0400, - [0x924900]=0x0800, - [0x6D6D55]=0x1000, - [0xDBDBAA]=0x2000, - [0x6D00FF]=0x4000, - [0xB6FF00]=0x8000 + [0xFFFFFF]=0x0001, + [0xFF0000]=0x0002, + [0x00FF00]=0x0004, + [0x0000FF]=0x0008, + [0x00FFFF]=0x0010, + [0xFF00FF]=0x0020, + [0xFFFF00]=0x0040, + [0xFF6D00]=0x0080, + [0x6DFF55]=0x0100, + [0x24FFFF]=0x0200, + [0x924900]=0x0400, + [0x6D6D55]=0x0800, + [0xDBDBAA]=0x1000, + [0x6D00FF]=0x2000, + [0xB6FF00]=0x4000, + [0x000000]=0x8000 } local fg,bg=0x6D6D55,0x000000 @@ -401,9 +400,10 @@ local ok, err = xpcall(function() allscreens[i].setTextScale(.5) allscreens[i].clear() allscreens[i].setCursorPos(1,1) - allscreens[i].write("Initializing...") end + allscreens[#allscreens+1] = apis.term + local EFI = { getEpochMs = function() return apis.os.epoch("utc") end, getUptime = function() return apis.os.clock() * 1000 end, @@ -424,22 +424,38 @@ local ok, err = xpcall(function() initfs=fs, disks=initFs, screenCtl={ - print = function(_, text) write(text .. "\n") end, - printInline = function(_, text) write(text) end, + print = function(_, text) + for i=1, #allscreens do + write(text.."\n", allscreens[i]) + end + end, + printInline = function(_, text) + for i=1, #allscreens do + write(text, allscreens[i]) + end + end, clear = function() - apis.term.clear() - apis.term.setCursorPos(1, 1) + for i=1, #allscreens do + allscreens[i].clear() + allscreens[i].setCursorPos(1, 1) + end end, - setCursorPos = function(_, x, y) - apis.term.setCursorPos(x, y) + resetCursor = function() + for i=1, #allscreens do + allscreens[i].setCursorPos(1, 1) + end end, - getCursorPos = function() return apis.term.getCursorPos() end, - getSize = function() return apis.term.getSize() end, setBackgroundColor = function(_, color) - apis.term.setBackgroundColor(aprox(color)) + bg=color + for i=1, #allscreens do + allscreens[i].setBackgroundColor(aprox(color)) + end end, setTextColor = function(_, color) - apis.term.setTextColor(aprox(color)) + fg=color + for i=1, #allscreens do + allscreens[i].setTextColor(aprox(color)) + end end, getBackgroundColor = function() return bg diff --git a/Src/Hyperion-firmware-cct/boot/cct/eeprom b/Src/Hyperion-firmware-cct/data/boot/cct/eeprom similarity index 100% rename from Src/Hyperion-firmware-cct/boot/cct/eeprom rename to Src/Hyperion-firmware-cct/data/boot/cct/eeprom diff --git a/Src/Hyperion-firmware-cct/boot/cct/initdisks b/Src/Hyperion-firmware-cct/data/boot/cct/initdisks similarity index 100% rename from Src/Hyperion-firmware-cct/boot/cct/initdisks rename to Src/Hyperion-firmware-cct/data/boot/cct/initdisks diff --git a/Src/Hyperion-firmware-cct/lib/modules/cc-tweaked/01_periph.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/01_periph.kmod similarity index 100% rename from Src/Hyperion-firmware-cct/lib/modules/cc-tweaked/01_periph.kmod rename to Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/01_periph.kmod diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod new file mode 100644 index 0000000..2e517bd --- /dev/null +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod @@ -0,0 +1 @@ +--:Minify:-- diff --git a/Src/Hyperion-firmware-cct/lib/modules/cc-tweaked/25_tty.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod similarity index 99% rename from Src/Hyperion-firmware-cct/lib/modules/cc-tweaked/25_tty.kmod rename to Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod index 8c9bcb0..e690425 100644 --- a/Src/Hyperion-firmware-cct/lib/modules/cc-tweaked/25_tty.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod @@ -246,7 +246,5 @@ kernel.cct.fifo=fifo newtty(kernel.apis.term, "1", fifo.pop) for i,v in ipairs({peripheral.find("monitor")}) do - v.setTextScale(.5) - v.write("Initializing...") newtty(v,tostring(i+1),function () end) end \ No newline at end of file diff --git a/Src/Hyperion-firmware-cct/lib/modules/cc-tweaked/30_deamon.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_deamon.kmod similarity index 100% rename from Src/Hyperion-firmware-cct/lib/modules/cc-tweaked/30_deamon.kmod rename to Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_deamon.kmod diff --git a/Src/Hyperion-firmware-cct/lib/modules/cc-tweaked/51_gpio.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/51_gpio.kmod similarity index 100% rename from Src/Hyperion-firmware-cct/lib/modules/cc-tweaked/51_gpio.kmod rename to Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/51_gpio.kmod diff --git a/Src/Hyperion-firmware-oc/boot/oc/boot.lua b/Src/Hyperion-firmware-oc/data/boot/oc/boot.lua similarity index 100% rename from Src/Hyperion-firmware-oc/boot/oc/boot.lua rename to Src/Hyperion-firmware-oc/data/boot/oc/boot.lua diff --git a/Src/Hyperion-firmware-oc/boot/oc/eeprom b/Src/Hyperion-firmware-oc/data/boot/oc/eeprom similarity index 100% rename from Src/Hyperion-firmware-oc/boot/oc/eeprom rename to Src/Hyperion-firmware-oc/data/boot/oc/eeprom diff --git a/Src/Hyperion-firmware-oc/boot/oc/initfs.lua b/Src/Hyperion-firmware-oc/data/boot/oc/initfs.lua similarity index 100% rename from Src/Hyperion-firmware-oc/boot/oc/initfs.lua rename to Src/Hyperion-firmware-oc/data/boot/oc/initfs.lua diff --git a/Src/Hyperion-kernel/boot/fstab b/Src/Hyperion-kernel/data/boot/fstab similarity index 100% rename from Src/Hyperion-kernel/boot/fstab rename to Src/Hyperion-kernel/data/boot/fstab diff --git a/Src/Hyperion-kernel/boot/initfs b/Src/Hyperion-kernel/data/boot/initfs similarity index 100% rename from Src/Hyperion-kernel/boot/initfs rename to Src/Hyperion-kernel/data/boot/initfs diff --git a/Src/Hyperion-kernel/boot/kernel.lua b/Src/Hyperion-kernel/data/boot/kernel.lua similarity index 93% rename from Src/Hyperion-kernel/boot/kernel.lua rename to Src/Hyperion-kernel/data/boot/kernel.lua index 4cc2099..3286917 100644 --- a/Src/Hyperion-kernel/boot/kernel.lua +++ b/Src/Hyperion-kernel/data/boot/kernel.lua @@ -7,7 +7,8 @@ local disks=EFI.disks local arch=EFI.architecture local kernel = {} kernel.LOG_Text="" -kernel.version="HyperionOS V1.2.4" +kernel.version="HyperionOS V1.2.4-dev_5" +kernel.tag="1.2.4-dev_5" kernel.process = "Kernel" kernel.users={[0]="root",[1]="User"} kernel.hostname = "hyperion" @@ -22,7 +23,7 @@ kernel._G=_G kernel.sleep=sleep _G.sleep=nil -local windowsExp = false +local windowsExp = true function kernel.log(msg, level, c) c=c or 0x6D6D6D @@ -51,7 +52,7 @@ function kernel.PANIC(msg) screen:setTextColor(0xFF0000) screen:setBackgroundColor(0x000000) screen:clear() - screen:setCursorPos(1,1) + screen:resetCursor() screen:print(kernel.LOG_Text) screen:print("KERNEL PANIC!\n"..msg.."\nSystem halted.") screen:print("Press any key to continue...") @@ -72,17 +73,11 @@ if windowsExp then screen:setTextColor(0xFFFFFF) screen:setBackgroundColor(0x0000FF) screen:clear() - local w,h = screen:getSize() - screen:setCursorPos(3,5) - screen:print(":(") - screen:setCursorPos(3,7) - screen:print("Your PC ran into a problem and needs to restart. We're just collecting some error") - screen:setCursorPos(3,8) - screen:print("info, and then we'll restart for you.\n") - screen:setCursorPos(3,h-5) - screen:print("Stop code: average windows experience") - screen:setCursorPos(1,h) - screen:print("Press any key to continue... jk reboot it yourself lazy") + screen:resetCursor() + screen:print("\n\n\n\n\n :(") + screen:print("\n Your PC ran into a problem and needs to restart. We're just collecting some error") + screen:print(" info, and then we'll restart for you.\n") + screen:print("\n\n\n Stop code: average windows experience") while true do end end @@ -254,6 +249,7 @@ end kernel.syscalls["time"]=function() return kernel.EFI:getEpochMs() end kernel.syscalls["date"]=function() return kernel.EFI:date() end kernel.syscalls["log"]=kernel.log +kernel.syscalls["tag"]=function() return kernel.tag end kernel.syscalls["getUptime"]=function() return kernel.EFI:getUptime() end kernel.syscalls["getUsername"]=function(uid) return kernel.users[uid or kernel.uid] end kernel.syscalls["getHostname"]=function() return kernel.hostname end diff --git a/Src/Hyperion-kernel/boot/safeboot.cfg b/Src/Hyperion-kernel/data/boot/safeboot.cfg similarity index 88% rename from Src/Hyperion-kernel/boot/safeboot.cfg rename to Src/Hyperion-kernel/data/boot/safeboot.cfg index 1c58e65..8005543 100644 --- a/Src/Hyperion-kernel/boot/safeboot.cfg +++ b/Src/Hyperion-kernel/data/boot/safeboot.cfg @@ -7,6 +7,5 @@ return { initPath = "/sbin/init", maxOpenFiles = 128, maxFilesPerTask = 16, - preempt=true, - logTaskExit=true + preempt=true } \ No newline at end of file diff --git a/Src/Hyperion-kernel/etc/passwd b/Src/Hyperion-kernel/data/etc/passwd similarity index 100% rename from Src/Hyperion-kernel/etc/passwd rename to Src/Hyperion-kernel/data/etc/passwd diff --git a/Src/Hyperion-kernel/etc/shadow b/Src/Hyperion-kernel/data/etc/shadow similarity index 100% rename from Src/Hyperion-kernel/etc/shadow rename to Src/Hyperion-kernel/data/etc/shadow diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/01_stdlib.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/01_stdlib.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/10_vfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod similarity index 97% rename from Src/Hyperion-kernel/lib/modules/hyperion/10_vfs.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod index 7633831..2aa8be6 100644 --- a/Src/Hyperion-kernel/lib/modules/hyperion/10_vfs.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod @@ -129,6 +129,8 @@ local function validateComponent(comp) end if lower == ".meta" then error("EINVAL: reserved path component: .meta", 3) + elseif lower:sub(#lower) == "." then + error("Cannot have empty name extention: " .. comp, 3) end end @@ -397,6 +399,10 @@ end local function getFileMeta(path, noFollow) local real = namei(path, noFollow) + if kernel.unixSockets[real] then + return kernel.unixSockets[real].meta + end + if real == "/" then return { etype = 0x00, owner = 0, group = 0, perms = 62, cmeta = "" } end @@ -596,8 +602,8 @@ function vfs.open(path, mode) if not disk then error("NODISK") end if (mode=="w" or mode=="a") and disk:isReadOnly() then error("ERDONLY") end - if kernel.unixSockets[normalizePath(path)] then - local meta = kernel.unixSockets[normalizePath(path)].meta + if kernel.unixSockets[namei(path)] then + local meta = kernel.unixSockets[namei(path)].meta if kernel.uid~=0 or kernel.uid~=meta.owner then local groups = (task and task.groups) or kernel.groups or {} local access=false @@ -606,7 +612,7 @@ function vfs.open(path, mode) end if not access then error("EACCES") end end - task[fd]=kernel.unixSockets[normalizePath(path)] + task[fd]=kernel.unixSockets[namei(path)] return fd end @@ -711,12 +717,11 @@ end function vfs.stat(path) local attrs - local meta + local disk, diskPath = resolvePath(path) + local meta = getFileMeta(path) if meta.etype == 0x02 then attrs = { size=0, modified=0, created=0 } else - local disk, diskPath = resolvePath(path) - meta = getFileMeta(path) local ok ok, attrs = pcall(disk.attributes, disk, diskPath) if not ok then attrs = { size=0, modified=0, created=0 } end @@ -856,13 +861,13 @@ function vfs.remove(path) local meta = getFileMeta(path, true) - if kernel.unixSockets and kernel.unixSockets[normalizePath(path)] then + if kernel.unixSockets[namei(path)] then if kernel.uid ~= 0 then - if kernel.unixSockets[normalizePath(path)].meta.owner~=kernel.uid then + if kernel.unixSockets[namei(path)].meta.owner~=kernel.uid then error("EACCES") end end - kernel.unixSockets[normalizePath(path)] = nil + kernel.unixSockets[namei(path)] = nil end if meta.etype == 0x01 then @@ -973,7 +978,7 @@ local function updateMeta(path, fn, noFollow) end function vfs.chmod(path, perms) - if kernel.unixSockets[normalizePath(path)] then error("EINVAL") end + if kernel.unixSockets[namei(path)] then error("EINVAL") end local disk = resolveMount(path) if disk:isReadOnly() then error("ERDONLY") end local meta = getFileMeta(path) @@ -985,12 +990,12 @@ end function vfs.fchmod(fd, perms) local file = kernel.currentTask.fd[fd] if not file then error("EBADF") end - if file.etype==0x02 then error("EINVAL") end + if file.meta.etype==0x02 then error("EINVAL") end vfs.chmod(file.path, perms) end function vfs.chown(path, uid, gid) - if kernel.unixSockets[normalizePath(path)] then error("EINVAL") end + if kernel.unixSockets[namei(path)] then error("EINVAL") end local disk = resolveMount(path) if disk:isReadOnly() then error("ERDONLY") end local _euid = (kernel.currentTask and (kernel.currentTask.euid or kernel.currentTask.uid)) or kernel.uid @@ -1001,14 +1006,14 @@ end function vfs.fchown(fd, uid, gid) local file = kernel.currentTask.fd[fd] if not file then error("EBADF") end - if file.etype==0x02 then error("EINVAL") end + if file.meta.etype==0x02 then error("EINVAL") end vfs.chown(file.path, uid, gid) end function vfs.exists(path) - if kernel.unixSockets[normalizePath(path)] then return true end + if kernel.unixSockets[namei(path)] then return true end local meta = getFileMeta(path, true) - if meta.etype == 0x01 then return true end + if meta.etype == 0x01 or meta.etype == 0x02 then return true end local ok, disk, diskPath = pcall(resolvePath, path) if not ok then return false end if disk:type(diskPath) then @@ -1021,7 +1026,7 @@ end function vfs.type(path) local meta = getFileMeta(path, true) if meta.etype == 0x01 then return "symlink" end - if kernel.unixSockets[normalizePath(path)] then + if kernel.unixSockets[namei(path)] then return "socket" end local ok, disk, diskPath = pcall(resolvePath, path) diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/11_require.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/11_require.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/11_require.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/11_require.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/12_devfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod similarity index 99% rename from Src/Hyperion-kernel/lib/modules/hyperion/12_devfs.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod index 317b09e..be427d5 100644 --- a/Src/Hyperion-kernel/lib/modules/hyperion/12_devfs.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod @@ -50,7 +50,7 @@ function proxy:type(path, mode) if type(step[steps[#steps]]) == "table" then return "directory" end - error(type(step[steps[#steps]])) + error("ENOENT") end function proxy:list(path) diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/12_procfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_procfs.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/12_procfs.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/12_procfs.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/12_tmpfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_tmpfs.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/12_tmpfs.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/12_tmpfs.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/13_loopdev.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/13_loopdev.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/13_loopdev.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/13_loopdev.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/19_fstab.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/19_fstab.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/19_fstab.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/19_fstab.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/20_signals.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/20_signals.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/20_signals.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/20_signals.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/20_socket.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod similarity index 77% rename from Src/Hyperion-kernel/lib/modules/hyperion/20_socket.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod index e69f1f5..18e280a 100644 --- a/Src/Hyperion-kernel/lib/modules/hyperion/20_socket.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod @@ -28,15 +28,15 @@ function socket.socket() local P=kernel.vfs.P local data=kernel.newFifo() local isClosed=false - kernel.vfs.newfd({ + return kernel.vfs.newfd({ handle={ - read=function() if isClosed then error("ECCON") end return data.read() end, - write=function() if isClosed then error("ECCON") end return data.write() end, + read=function() if isClosed then error("ECCON") end return data.pop() end, + write=function(data) if isClosed then error("ECCON") end return data.push(data) end, close=function() isClosed = true end }, type="socket", refcount=1, - + socket={}, meta={ owner=kernel.currentTask.uid, group=kernel.currentTask.uid, @@ -48,11 +48,20 @@ function socket.socket() end function socket.connect(fd, address) - + local handler + for k, v in pairs(socket.handlers) do + if string.hasPrefix(address, k) then + handler=v + end + end + handler.connect(kernel.currentTask.fd[fd], address) end function socket.listen(fd, backlog) - + error("Not Implemented") end -kernel.log("Loaded socket module") +local sys=kernel.syscalls +sys["socket"]=socket.socket + +kernel.log("Loaded socket module") \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/21_unixsockets.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/21_unixsockets.kmod new file mode 100644 index 0000000..a145249 --- /dev/null +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/21_unixsockets.kmod @@ -0,0 +1,4 @@ +--:Minify:-- +local kernel=... +kernel.unixSockets={} +local socket=kernel.socket diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/30_userspace.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/30_userspace.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/30_userspace.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/30_userspace.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/40_auth.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/40_auth.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/40_auth.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/40_auth.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/45_hypervisor.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod similarity index 93% rename from Src/Hyperion-kernel/lib/modules/hyperion/45_hypervisor.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod index f859fcf..ad4606e 100644 --- a/Src/Hyperion-kernel/lib/modules/hyperion/45_hypervisor.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod @@ -203,12 +203,14 @@ function sys.collect(pid) end end -function sys.kill(pid) +function sys.kill(pid, force) local task = tasks[tostring(pid)] if not task then return false, "Task does not exist" elseif task.status == "Z" then return false, "Task is already dead" + elseif task.status == "D" and not force then + return false, "Cannot kill task waiting for IO" end local caller = kernel.currentTask local ceuid = caller and (caller.euid or caller.uid) or kernel.uid @@ -223,10 +225,14 @@ function sys.stop(pid) local task = tasks[tostring(pid)] if not task then return false, "Task does not exist" - elseif task.status ~= "R" then + elseif task.status ~= "R" and task.status ~= "S" then return false, "Cannot stop non-running task" else - task.status = "T" + if task.status == "S" then + task.status = "ST" + else + task.status = "T" + end return true end end @@ -235,10 +241,14 @@ function sys.continue(pid) local task = tasks[tostring(pid)] if not task then return false, "Task does not exist" - elseif task.status ~= "T" then + elseif task.status ~= "T" and task.status ~= "ST" then return false, "Task is not stopped" else - task.status = "R" + if task.status == "ST" then + task.status = "S" + else + task.status = "R" + end return true end end @@ -351,6 +361,11 @@ function kernel.main() task.sleep = 0 end + if task.status == "ST" and kernel.EFI:getEpochMs() >= task.sleep then + task.status = "T" + task.sleep = 0 + end + if task.status == "D" then if task.ksh then coroutine.resume(task.ksh) @@ -364,14 +379,19 @@ function kernel.main() if task.sigq and #task.sigq ~= 0 and task.sigh then local coro = coroutine.create(task.sigh) - local status,err=coroutine.resumeWithTimeout(coro, 100, table.remove(task.sigq, 1)) - if status=="error" then - task.sigd.error=err + local status,err + if kernel.config.preempt then + status,err=coroutine.resumeWithTimeout(coro, 100, table.remove(task.sigq, 1)) + else + status,err=coroutine.resume(coro, table.remove(task.sigq, 1)) + end + if status=="error" or status==false then + task.sigd.error=err or "Unknown" task.sigd.active=false task.sigh=nil task.sigq=nil task.sigd=nil - elseif status=="success" then + elseif status=="success" or status==true then if err=="syscall" then task.sigd.error="Cannot execute syscalls from signals" task.sigd.active=false diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/47_dbg.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/47_dbg.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/47_dbg.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/47_dbg.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/50_gpio.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/50_gpio.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/50_gpio.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/50_gpio.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/70_stdlibadv.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/70_stdlibadv.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/70_stdlibadv.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/70_stdlibadv.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/90_init.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/90_init.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/90_init.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/90_init.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/91_login.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/91_login.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/91_login.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/91_login.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/92_setup.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/92_setup.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/92_setup.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/92_setup.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/99_final.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/99_final.kmod similarity index 100% rename from Src/Hyperion-kernel/lib/modules/hyperion/99_final.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/99_final.kmod diff --git a/Src/Hyperion-kernel/lib/modules/hyperion/21_unixsockets.kmod b/Src/Hyperion-kernel/lib/modules/hyperion/21_unixsockets.kmod deleted file mode 100644 index a437c9c..0000000 --- a/Src/Hyperion-kernel/lib/modules/hyperion/21_unixsockets.kmod +++ /dev/null @@ -1,3 +0,0 @@ ---:Minify:-- -local kernel=... -kernel.unixSockets={} \ No newline at end of file diff --git a/Src/bit32/lib/bit32 b/Src/bit32/data/lib/bit32 similarity index 100% rename from Src/bit32/lib/bit32 rename to Src/bit32/data/lib/bit32 diff --git a/Src/blake2s/lib/crypto/blake2s b/Src/blake2s/data/lib/crypto/blake2s similarity index 100% rename from Src/blake2s/lib/crypto/blake2s rename to Src/blake2s/data/lib/crypto/blake2s diff --git a/Src/deflate/lib/LibDeflate b/Src/deflate/data/lib/LibDeflate similarity index 100% rename from Src/deflate/lib/LibDeflate rename to Src/deflate/data/lib/LibDeflate diff --git a/Src/deflate/lib/deflate b/Src/deflate/data/lib/deflate similarity index 100% rename from Src/deflate/lib/deflate rename to Src/deflate/data/lib/deflate diff --git a/Src/hysh/bin/chattr b/Src/hysh/data/bin/chattr similarity index 100% rename from Src/hysh/bin/chattr rename to Src/hysh/data/bin/chattr diff --git a/Src/hysh/bin/chgrp b/Src/hysh/data/bin/chgrp similarity index 100% rename from Src/hysh/bin/chgrp rename to Src/hysh/data/bin/chgrp diff --git a/Src/hysh/bin/chmod b/Src/hysh/data/bin/chmod similarity index 100% rename from Src/hysh/bin/chmod rename to Src/hysh/data/bin/chmod diff --git a/Src/hysh/bin/chown b/Src/hysh/data/bin/chown similarity index 100% rename from Src/hysh/bin/chown rename to Src/hysh/data/bin/chown diff --git a/Src/hysh/bin/chroot b/Src/hysh/data/bin/chroot similarity index 100% rename from Src/hysh/bin/chroot rename to Src/hysh/data/bin/chroot diff --git a/Src/hysh/bin/help b/Src/hysh/data/bin/help similarity index 100% rename from Src/hysh/bin/help rename to Src/hysh/data/bin/help diff --git a/Src/hysh/bin/hfetch b/Src/hysh/data/bin/hfetch similarity index 100% rename from Src/hysh/bin/hfetch rename to Src/hysh/data/bin/hfetch diff --git a/Src/hysh/bin/hysh b/Src/hysh/data/bin/hysh similarity index 99% rename from Src/hysh/bin/hysh rename to Src/hysh/data/bin/hysh index 60dd209..6bf3655 100644 --- a/Src/hysh/bin/hysh +++ b/Src/hysh/data/bin/hysh @@ -827,6 +827,12 @@ builtinCmds.df = function(...) end end +builtinCmds.ops = function() + for i,v in pairs(math) do + print(i) + end +end + local function listDir(dir, prefix) local ok, entries = pcall(syscall.listdir, dir) if not ok or not entries then return {} end @@ -981,6 +987,7 @@ local function doTabComplete(input, cursorPos) end end +local lastghost="" local function getUserInput() syscall.devctl(1,"sfgc",0x00FF00) syscall.write(1, userhost) @@ -1147,7 +1154,7 @@ end local function runCommand(command) do - local func = load("return "..command, "@equation", "t", {}) + local func = load("return "..command, "@equation", "t", math) if func then local ok, result = pcall(func) if ok and type(result)=="number" then print(result); return end diff --git a/Src/hysh/bin/id b/Src/hysh/data/bin/id similarity index 100% rename from Src/hysh/bin/id rename to Src/hysh/data/bin/id diff --git a/Src/hysh/bin/ll b/Src/hysh/data/bin/ll similarity index 100% rename from Src/hysh/bin/ll rename to Src/hysh/data/bin/ll diff --git a/Src/hysh/bin/ln b/Src/hysh/data/bin/ln similarity index 100% rename from Src/hysh/bin/ln rename to Src/hysh/data/bin/ln diff --git a/Src/hysh/bin/login b/Src/hysh/data/bin/login similarity index 100% rename from Src/hysh/bin/login rename to Src/hysh/data/bin/login diff --git a/Src/hysh/bin/loimgcreate b/Src/hysh/data/bin/loimgcreate similarity index 100% rename from Src/hysh/bin/loimgcreate rename to Src/hysh/data/bin/loimgcreate diff --git a/Src/hysh/bin/losetup b/Src/hysh/data/bin/losetup similarity index 100% rename from Src/hysh/bin/losetup rename to Src/hysh/data/bin/losetup diff --git a/Src/hysh/bin/ls b/Src/hysh/data/bin/ls similarity index 99% rename from Src/hysh/bin/ls rename to Src/hysh/data/bin/ls index a37877f..ef0daaa 100644 --- a/Src/hysh/bin/ls +++ b/Src/hysh/data/bin/ls @@ -95,6 +95,8 @@ local screenSizeStr = syscall.devctl(1, "size") local sizeX = tonumber(screenSizeStr:match("^(%d+)")) or 80 local list = fs.list(dir) +list[#list+1] = "." +list[#list+1] = ".." if not cloptions.a then for i = #list, 1, -1 do if list[i]:sub(1, 1) == "." then table.remove(list, i) end diff --git a/Src/hysh/bin/lsusers b/Src/hysh/data/bin/lsusers similarity index 100% rename from Src/hysh/bin/lsusers rename to Src/hysh/data/bin/lsusers diff --git a/Src/hysh/bin/mount b/Src/hysh/data/bin/mount similarity index 100% rename from Src/hysh/bin/mount rename to Src/hysh/data/bin/mount diff --git a/Src/hysh/bin/passwd b/Src/hysh/data/bin/passwd similarity index 100% rename from Src/hysh/bin/passwd rename to Src/hysh/data/bin/passwd diff --git a/Src/hysh/bin/ps b/Src/hysh/data/bin/ps similarity index 100% rename from Src/hysh/bin/ps rename to Src/hysh/data/bin/ps diff --git a/Src/hysh/bin/readlink b/Src/hysh/data/bin/readlink similarity index 100% rename from Src/hysh/bin/readlink rename to Src/hysh/data/bin/readlink diff --git a/Src/sed/bin/sed b/Src/hysh/data/bin/sed similarity index 100% rename from Src/sed/bin/sed rename to Src/hysh/data/bin/sed diff --git a/Src/hysh/bin/su b/Src/hysh/data/bin/su similarity index 100% rename from Src/hysh/bin/su rename to Src/hysh/data/bin/su diff --git a/Src/hysh/bin/sudo b/Src/hysh/data/bin/sudo similarity index 100% rename from Src/hysh/bin/sudo rename to Src/hysh/data/bin/sudo diff --git a/Src/hysh/bin/sysdump b/Src/hysh/data/bin/sysdump similarity index 100% rename from Src/hysh/bin/sysdump rename to Src/hysh/data/bin/sysdump diff --git a/Src/hysh/bin/umount b/Src/hysh/data/bin/umount similarity index 100% rename from Src/hysh/bin/umount rename to Src/hysh/data/bin/umount diff --git a/Src/hysh/bin/useradd b/Src/hysh/data/bin/useradd similarity index 100% rename from Src/hysh/bin/useradd rename to Src/hysh/data/bin/useradd diff --git a/Src/hysh/bin/userdel b/Src/hysh/data/bin/userdel similarity index 100% rename from Src/hysh/bin/userdel rename to Src/hysh/data/bin/userdel diff --git a/Src/hysh/bin/usermod b/Src/hysh/data/bin/usermod similarity index 100% rename from Src/hysh/bin/usermod rename to Src/hysh/data/bin/usermod diff --git a/Src/hysh/bin/yes b/Src/hysh/data/bin/yes similarity index 100% rename from Src/hysh/bin/yes rename to Src/hysh/data/bin/yes diff --git a/Src/iniparse/lib/iniparse b/Src/iniparse/data/lib/iniparse similarity index 100% rename from Src/iniparse/lib/iniparse rename to Src/iniparse/data/lib/iniparse diff --git a/Src/install.json b/Src/install.json index 101d46d..3a0502f 100644 --- a/Src/install.json +++ b/Src/install.json @@ -4,5 +4,9 @@ "hysh", "lua", "micro", - "sysinit" + "sysinit", + "bit32", + "json", + "muxzcat", + "spm" ] \ No newline at end of file diff --git a/Src/json/lib/json b/Src/json/data/lib/json similarity index 100% rename from Src/json/lib/json rename to Src/json/data/lib/json diff --git a/Src/lua/bin/lua b/Src/lua/data/bin/lua similarity index 99% rename from Src/lua/bin/lua rename to Src/lua/data/bin/lua index 894d07f..14c7cec 100644 --- a/Src/lua/bin/lua +++ b/Src/lua/data/bin/lua @@ -300,6 +300,7 @@ local function getUserInput(prompt, history) end c(C_PROMPT); w("HyperionOS " .. _VERSION .. "\n") +w("Type \"exit()\" to exit.") c(C_NIL) w("Interactive Lua REPL. exit() to quit.\n\n") c(1) diff --git a/Src/micro/bin/micro b/Src/micro/data/bin/micro similarity index 100% rename from Src/micro/bin/micro rename to Src/micro/data/bin/micro diff --git a/Src/spm/bin/spm b/Src/spm/data/bin/spm similarity index 100% rename from Src/spm/bin/spm rename to Src/spm/data/bin/spm diff --git a/Src/sysinit/$PKGCONFIG.ini b/Src/sysinit/$PKGCONFIG.ini deleted file mode 100644 index c5153d4..0000000 --- a/Src/sysinit/$PKGCONFIG.ini +++ /dev/null @@ -1 +0,0 @@ -[symlinks] diff --git a/Src/sysinit/sbin/init b/Src/sysinit/data/sbin/init similarity index 100% rename from Src/sysinit/sbin/init rename to Src/sysinit/data/sbin/init diff --git a/Src/sysinit/usr/lib/sysinit/sysinit b/Src/sysinit/data/usr/lib/sysinit/sysinit similarity index 100% rename from Src/sysinit/usr/lib/sysinit/sysinit rename to Src/sysinit/data/usr/lib/sysinit/sysinit diff --git a/Src/xz/data/lib/xz b/Src/xz/data/lib/xz new file mode 100644 index 0000000..6254bfc --- /dev/null +++ b/Src/xz/data/lib/xz @@ -0,0 +1,1973 @@ +--[[ + XZ/LZMA decompressor ported from https://github.com/pts/muxzcat + Licensed under GNU GPL 2.0 or later + This should work under all Lua 5.1+ + To use: + muxzcat.DecompressXzOrLzmaFile(input, output) will read an XZ/LZMA file from input (FILE* or path) and write the result to output (FILE* or path) + muxzcat.DecompressXzOrLzmaString(input) will decompress a loaded XZ/LZMA file and returns the result + muxzcat.GetError(num) will return a string representation for an error code + muxzcat.ErrorCodes is a table that reverses GetError() + Written by pts@fazekas.hu at Sat Feb 2 13:28:42 CET 2019 + Ported to Lua by JackMacWindows +]] + +local bitlib +if bit32 ~= nil then bitlib = bit32 +elseif pcall(require, "bit32") then bitlib = require "bit32" +elseif pcall(require, "bit") then bitlib = require "bit" +elseif bit ~= nil then bitlib = bit +else + --[[--------------- + LuaBit v0.4 + ------------------- + a bitwise operation lib for lua. + + http: + + How to use: + ------------------- + bit.bnot(n) -- bitwise not (~n) + bit.band(m, n) -- bitwise and (m & n) + bit.bor(m, n) -- bitwise or (m | n) + bit.bxor(m, n) -- bitwise xor (m ^ n) + bit.brshift(n, bits) -- right shift (n >> bits) + bit.blshift(n, bits) -- left shift (n << bits) + bit.blogic_rshift(n, bits) -- logic right shift(zero fill >>>) + + Please note that bit.brshift and bit.blshift only support number within + 32 bits. + + 2 utility functions are provided too: + bit.tobits(n) -- convert n into a bit table(which is a 1/0 sequence) + -- high bits first + bit.tonumb(bit_tbl) -- convert a bit table into a number + ------------------- + + Under the MIT license. + + copyright(c) 2006~2007 hanzhao (abrash_han@hotmail.com) + --]]--------------- + ------------------------ + -- bit lib implementions + + local function check_int(n) + -- checking not float + if(n - math.floor(n) > 0) then + error("trying to use bitwise operation on non-integer!") + end + end + + local function to_bits(n) + check_int(n) + if(n < 0) then + -- negative + return to_bits(bitlib.bnot(math.abs(n)) + 1) + end + -- to bits table + local tbl = {} + local cnt = 1 + while (n > 0) do + local last = math.mod(n,2) + if(last == 1) then + tbl[cnt] = 1 + else + tbl[cnt] = 0 + end + n = (n-last)/2 + cnt = cnt + 1 + end + + return tbl + end + + local function tbl_to_number(tbl) + local n = table.getn(tbl) + + local rslt = 0 + local power = 1 + for i = 1, n do + rslt = rslt + tbl[i]*power + power = power*2 + end + + return rslt + end + + local function expand(tbl_m, tbl_n) + local big = {} + local small = {} + if(table.getn(tbl_m) > table.getn(tbl_n)) then + big = tbl_m + small = tbl_n + else + big = tbl_n + small = tbl_m + end + -- expand small + for i = table.getn(small) + 1, table.getn(big) do + small[i] = 0 + end + + end + + local function bit_or(m, n) + local tbl_m = to_bits(m) + local tbl_n = to_bits(n) + expand(tbl_m, tbl_n) + + local tbl = {} + local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n)) + for i = 1, rslt do + if(tbl_m[i]== 0 and tbl_n[i] == 0) then + tbl[i] = 0 + else + tbl[i] = 1 + end + end + + return tbl_to_number(tbl) + end + + local function bit_and(m, n) + local tbl_m = to_bits(m) + local tbl_n = to_bits(n) + expand(tbl_m, tbl_n) + + local tbl = {} + local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n)) + for i = 1, rslt do + if(tbl_m[i]== 0 or tbl_n[i] == 0) then + tbl[i] = 0 + else + tbl[i] = 1 + end + end + + return tbl_to_number(tbl) + end + + local function bit_not(n) + + local tbl = to_bits(n) + local size = math.max(table.getn(tbl), 32) + for i = 1, size do + if(tbl[i] == 1) then + tbl[i] = 0 + else + tbl[i] = 1 + end + end + return tbl_to_number(tbl) + end + + local function bit_xor(m, n) + local tbl_m = to_bits(m) + local tbl_n = to_bits(n) + expand(tbl_m, tbl_n) + + local tbl = {} + local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n)) + for i = 1, rslt do + if(tbl_m[i] ~= tbl_n[i]) then + tbl[i] = 1 + else + tbl[i] = 0 + end + end + + --table.foreach(tbl, --print) + + return tbl_to_number(tbl) + end + + local function bit_rshift(n, bits) + check_int(n) + + local high_bit = 0 + if(n < 0) then + -- negative + n = bit_not(math.abs(n)) + 1 + high_bit = 2147483648 -- 0x80000000 + end + + for i=1, bits do + n = n/2 + n = bit_or(math.floor(n), high_bit) + end + return math.floor(n) + end + + -- logic rightshift assures zero filling shift + local function bit_logic_rshift(n, bits) + check_int(n) + if(n < 0) then + -- negative + n = bit_not(math.abs(n)) + 1 + end + for i=1, bits do + n = n/2 + end + return math.floor(n) + end + + local function bit_lshift(n, bits) + check_int(n) + + if(n < 0) then + -- negative + n = bit_not(math.abs(n)) + 1 + end + + for i=1, bits do + n = n*2 + end + return bit_and(n, 4294967295) -- 0xFFFFFFFF + end + + -------------------- + -- bit lib interface + + bitlib = { + -- bit operations + bnot = bit_not, + band = bit_and, + bor = bit_or, + bxor = bit_xor, + brshift = bit_rshift, + blshift = bit_lshift, + blogic_rshift = bit_logic_rshift, + } +end +if bitlib.blogic_rshift then + bitlib = { + arshift = bitlib.brshift, + band = bitlib.band, + bnot = bitlib.bnot, + bor = bitlib.bor, + btest = function(a, b) return bitlib.band(a, b) ~= 0 end, + bxor = bitlib.bxor, + lshift = bitlib.blshift, + rshift = bitlib.blogic_rshift + } +end + +local band = {} +local bor = {} +local bxor = {} +local bnot = {} +local blshift = {} +local brshift = {} + +setmetatable(band, {__sub = function(lhs) + local mt = {lhs, __sub = function(self, b) return bitlib.band(self[1], b) end} + return setmetatable(mt, mt) +end}) + +setmetatable(bor, {__sub = function(lhs) + local mt = {lhs, __sub = function(self, b) return bitlib.bor(self[1], b) end} + return setmetatable(mt, mt) +end}) + +setmetatable(bxor, {__sub = function(lhs) + local mt = {lhs, __sub = function(self, b) return bitlib.bxor(self[1], b) end} + return setmetatable(mt, mt) +end}) + +setmetatable(blshift, {__sub = function(lhs) + local mt = {lhs, __sub = function(self, b) return bitlib.lshift(self[1], b) end} + return setmetatable(mt, mt) +end}) + +setmetatable(brshift, {__sub = function(lhs) + local mt = {lhs, __sub = function(self, b) return bitlib.rshift(self[1], b) end} + return setmetatable(mt, mt) +end}) + +setmetatable(bnot, {__sub = function(_, rhs) return bitlib.bnot(rhs) end}) + +local str_input, str_output + +local function writeTableSeq(tab, i, n, ...) if n ~= nil then tab[i] = n return writeTableSeq(tab, i+1, ...) end end + +local stdin=0 +local stdout=1 + +local function READ_FROM_STDIN_TO_ARY8(a, fromIdx, size) + local str + if str_input then + str, str_input = str_input:sub(1, size), str_input:sub(size+1) + for i = 1, #str, 256 do writeTableSeq(a, fromIdx + i - 1, str:byte(i, i + 256)) end + return #str + else + str = syscall.read(stdin,size) + for i = 1, #str, 256 do writeTableSeq(a, fromIdx + i - 1, str:byte(i, i + 256)) end + --assert(#a - fromIdx == #str - 1, (#a - fromIdx) .. ", " .. #str .. ", " .. size) + return #str + end +end + +local function readTableSeq(tab, i, j) if i == j then return tab[i] elseif i > j then return nil else return tab[i], readTableSeq(tab, i+1, j) end end + +local function WRITE_TO_STDOUT_FROM_ARY8(a, fromIdx, size) + if str_output then + for i = fromIdx, fromIdx + size - 1, 256 do str_output = str_output .. string.char(readTableSeq(a, i, math.min(fromIdx + size - 1, i + 255))) end + return size + else + for i = 1, size, 256 do syscall.write(stdout,string.char(readTableSeq(a, i+fromIdx-1, math.min(fromIdx + size - 1, i + fromIdx + 254)))) end + return size + end +end + +local bufCur = 0; +local dicSize = 0; +local range = 0; +local code = 0; +local dicPos = 0; +local dicBufSize = 0; +local processedPos = 0; +local checkDicSize = 0; +local state = 0; +local rep0 = 1; +local rep1 = 1; +local rep2 = 1; +local rep3 = 1; +local remainLen = 0; +local tempBufSize = 0; +local readCur = 0; +local readEnd = 0; +local needFlush = 0; +local needInitLzma = 0; +local needInitDic = 0; +local needInitState = 0; +local needInitProp = 0; +local lc = 0; +local lp = 0; +local pb = 0; +local lcm8 = 0; +local _probs16 = {} +local probs16 = setmetatable({}, {__index = function(_, idx) return _probs16[idx] --[[-band- 0xFFFF]] end, __newindex = function(_, idx, val) _probs16[idx] = val -band- 0xFFFF end}); +local _readBuf8 = {} +local readBuf8 = setmetatable({}, {__index = function(_, idx) return _readBuf8[idx] --[[-band- 0xFF]] end, __newindex = function(_, idx, val) _readBuf8[idx] = val -band- 0xFF end}); +local _dic8 = {} +local dic8 = setmetatable({}, {__index = function(_, idx) return _dic8[idx] --[[-band- 0xFF]] end, __newindex = function(_, idx, val) _dic8[idx] = val -band- 0xFF end}); + +local function ResetGlobals() + bufCur = 0; + dicSize = 0; + range = 0; + code = 0; + dicPos = 0; + dicBufSize = 0; + processedPos = 0; + checkDicSize = 0; + state = 0; + rep0 = 1; + rep1 = 1; + rep2 = 1; + rep3 = 1; + remainLen = 0; + tempBufSize = 0; + readCur = 0; + readEnd = 0; + needFlush = 0; + needInitLzma = 0; + needInitDic = 0; + needInitState = 0; + needInitProp = 0; + lc = 0; + lp = 0; + pb = 0; + lcm8 = 0; + _probs16 = {} + _readBuf8 = {} + _dic8 = {} + stdin=0 + stdout=1 +end + +local function LzmaDec_WriteRem(wrDicLimit) + + if (((remainLen) ~= (0)) and ((remainLen) < (274))) then + local wrLen = remainLen; + if (((wrDicLimit - dicPos) < (wrLen))) then + wrLen = wrDicLimit - dicPos ; + end + if (((checkDicSize) == (0)) and ((dicSize - processedPos) <= (wrLen))) then + checkDicSize = dicSize; + end + processedPos = processedPos + wrLen; + remainLen = remainLen - wrLen; + while (((wrLen) ~= (0))) do + wrLen=wrLen-1; + dic8[dicPos] = dic8[(dicPos - rep0) + (((dicPos) < (rep0)) and dicBufSize or 0)] -band- 0xFF; + dicPos=dicPos+1; + end + end +end + + +local function LzmaDec_DecodeReal2(drDicLimit, drBufLimit) + local pbMask = ((1) -blshift- (pb)) - 1; + local lpMask = ((1) -blshift- (lp)) - 1; + local drI = 0; + local lastTime + if textutils then + os.queueEvent("nosleep") + lastTime = os.epoch("utc") + end + + repeat + local drDicLimit2 = (((checkDicSize) == (0)) and ((dicSize - processedPos) < (drDicLimit - dicPos))) and (dicPos + (dicSize - processedPos)) or drDicLimit; + --print("drDicLimit2", drDicLimit2, "checkDicSize", checkDicSize, "dicSize", dicSize, "processedPos", processedPos, "drDicLimit", drDicLimit, "dicPos", dicPos) + remainLen = 0; + repeat + local drProbIdx = 0; + local drBound = 0; + local drTtt = 0; + local distance = 0; + local drPosState = processedPos -band- pbMask; + if textutils and os.epoch("utc") - lastTime > 3000 then + --write(".") + lastTime = os.epoch("utc") + os.queueEvent(os.pullEvent()) + end + --print(rep0, rep1, rep2, rep3) + drProbIdx = 0 + (state -blshift- (4)) + drPosState ; + drTtt = probs16[drProbIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur = bufCur + 1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + local drSymbol = 0; + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + range = (drBound) ; + probs16[drProbIdx] = drTtt + ((bitlib.rshift((2048 - drTtt), (5)))); + drProbIdx = 1846 ; + if (((checkDicSize) ~= (0)) or ((processedPos) ~= (0))) then + drProbIdx = drProbIdx + (768 * (((processedPos -band- lpMask) -blshift- lc) + (bitlib.rshift((dic8[(((dicPos) == (0)) and dicBufSize or dicPos) - 1]), (lcm8))))) ; + end + if (((state) < (7))) then + state = state - ((((state) < (4))) and state or 3); + drSymbol = 1 ; + repeat + drTtt = probs16[drProbIdx + drSymbol] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = ((bitlib.rshift((range), 11))) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx + drSymbol] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drSymbol = (drSymbol + drSymbol); + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx + drSymbol] = drTtt - (bitlib.rshift((drTtt), (5))); + drSymbol = (drSymbol + drSymbol) + 1; + end + until not (((drSymbol) < (0x100))) + else + local drMatchByte = dic8[(dicPos - rep0) + (((dicPos) < (rep0)) and dicBufSize or 0)]; + local drMatchMask = 0x100; + state = state - (((state) < (10)) and 3 or 6); + drSymbol = 1 ; + repeat + local drBit; + local drProbLitIdx; + assert(drMatchMask == 0 or drMatchMask == 0x100); + drMatchByte = drMatchByte -blshift- 1 ; + drBit = (drMatchByte -band- drMatchMask) ; + drProbLitIdx = drProbIdx + drMatchMask + drBit + drSymbol ; + drTtt = probs16[drProbLitIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbLitIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drSymbol = (drSymbol + drSymbol) ; + drMatchMask = drMatchMask -band- (bnot-drBit) ; + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbLitIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + drSymbol = (drSymbol + drSymbol) + 1 ; + drMatchMask = drMatchMask -band- drBit ; + end + until not (((drSymbol) < (0x100))); + end + dic8[dicPos] = drSymbol -band- 0xFF; + dicPos=dicPos+1; + processedPos=processedPos+1; + --print("continue2") + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + drProbIdx = 192 + state ; + drTtt = probs16[drProbIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + local shouldContinue = true + if (((code) < (drBound))) then + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + range = (drBound) ; + probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + state = state + 12; + drProbIdx = 818 ; + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + if (((checkDicSize) == (0)) and ((processedPos) == (0))) then + --print("A") + return 1; + end + drProbIdx = 204 + state ; + drTtt = probs16[drProbIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + range = (drBound) ; + probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drProbIdx = 240 + (state -blshift- (4)) + drPosState ; + drTtt = probs16[drProbIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + dic8[dicPos] = dic8[(dicPos - rep0) + (((dicPos) < (rep0)) and dicBufSize or 0)] -band- 0xFF; + dicPos=dicPos+1; + processedPos=processedPos+1; + state = ((state) < (7)) and 9 or 11; + --print("continue") + shouldContinue = false + end + if shouldContinue then + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + end + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + drProbIdx = 216 + state ; + drTtt = probs16[drProbIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + distance = rep1 ; + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + drProbIdx = 228 + state ; + drTtt = probs16[drProbIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + distance = rep2 ; + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + distance = rep3 ; + rep3 = rep2; + end + rep2 = rep1; + end + rep1 = rep0; + rep0 = distance; + end + if shouldContinue then + state = ((state) < (7)) and 8 or 11; + drProbIdx = 1332 ; + end + end + if shouldContinue then + --print(distance) + do + local drLimitSub; + local drOffset; + local drProbLenIdx = drProbIdx + 0; + drTtt = probs16[drProbLenIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + range = (drBound) ; + probs16[drProbLenIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drProbLenIdx = drProbIdx + 2 + (drPosState -blshift- (3)) ; + drOffset = 0 ; + drLimitSub = (8) ; + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbLenIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + drProbLenIdx = drProbIdx + 1 ; + drTtt = probs16[drProbLenIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + range = (drBound) ; + probs16[drProbLenIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drProbLenIdx = drProbIdx + 130 + (drPosState -blshift- (3)) ; + drOffset = 8 ; + drLimitSub = 8 ; + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbLenIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + drProbLenIdx = drProbIdx + 258 ; + drOffset = 8 + 8 ; + drLimitSub = 256 ; + end + end + do + remainLen = (1) ; + repeat + drTtt = probs16[(drProbLenIdx + remainLen)] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[(drProbLenIdx + remainLen)] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + remainLen = ((remainLen + remainLen)); + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[(drProbLenIdx + remainLen)] = drTtt - (bitlib.rshift((drTtt), (5))); + remainLen = ((remainLen + remainLen) + 1); + end + until not (((remainLen) < (drLimitSub))); + remainLen = remainLen - (drLimitSub) ; + end + remainLen = remainLen + (drOffset) ; + end + + if (((state) >= (12))) then + drProbIdx = 432 + ((((remainLen) < (4)) and remainLen or 4 - 1) -blshift- (6)) ; + do + distance = 1 ; + repeat + drTtt = probs16[(drProbIdx + distance)] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[(drProbIdx + distance)] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + distance = (distance + distance); + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[(drProbIdx + distance)] = drTtt - (bitlib.rshift((drTtt), (5))); + distance = (distance + distance) + 1; + end + until not (((distance) < ((64)))); + distance = distance - (64) ; + end + assert((distance <= 0x7fffffff) and ((distance) < (64))); + if (((distance) >= (4))) then + local drPosSlot = distance; + local drDirectBitCount = (bitlib.rshift((distance), (1))) - 1; + distance = (2 -bor- (distance -band- 1)) ; + if (((drPosSlot) < (14))) then + distance = distance -blshift- drDirectBitCount ; + drProbIdx = 688 + distance - drPosSlot - 1 ; + do + local mask = 1; + drI = 1; + repeat + drTtt = probs16[drProbIdx + drI] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drI = (drI + drI); + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); + drI = (drI + drI) + 1 ; + distance = distance -bor- mask ; + end + mask = mask -blshift- 1 ; + drDirectBitCount = drDirectBitCount - 1 + until not (((drDirectBitCount) ~= (0))); + end + else + drDirectBitCount = drDirectBitCount - 4 ; + repeat + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + + range = ((bitlib.rshift((range), 1))); + if (((code - range) -band- 0x80000000 ~= 0)) then + distance = distance -blshift- 1; + else + code = code - (range); + + distance = (distance -blshift- 1) + 1; + end + drDirectBitCount = drDirectBitCount-1; + until not (((drDirectBitCount) ~= (0))); + drProbIdx = 802 ; + distance = distance -blshift- 4 ; + do + drI = 1; + drTtt = probs16[drProbIdx + drI]; + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drI = (drI + drI); + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); + drI = (drI + drI) + 1 ; + distance = distance -bor- 1 ; + end + drTtt = probs16[drProbIdx + drI]; + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drI = (drI + drI); + else range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); + drI = (drI + drI) + 1 ; + distance = distance -bor- 2 ; + end + drTtt = probs16[drProbIdx + drI]; + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drI = (drI + drI); + else range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); + drI = (drI + drI) + 1 ; + distance = distance -bor- 4 ; + end + drTtt = probs16[drProbIdx + drI]; + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drI = (drI + drI); + else range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); + drI = (drI + drI) + 1 ; + distance = distance -bor- 8 ; + end + end + if (((bnot-distance) == 0)) then + remainLen = remainLen + (274) ; + state = state - 12; + --print("break") + break; + end + end + end + + assert((distance <= 0x7fffffff) and ((distance) <= (1610612736))); + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + rep0 = distance + 1; + if (((checkDicSize) == (0))) then + if (((distance) >= (processedPos))) then + --print("B") + return 1; + end + else + if (((distance) >= (checkDicSize))) then + --print("C") + return 1; + end + end + state = ((state) < (12 + 7)) and 7 or 7 + 3; + end + + remainLen = remainLen + (2) ; + + if (((drDicLimit2) == (dicPos))) then + --print("D") + return 1; + end + do + local drRem = drDicLimit2 - dicPos; + local curLen = (((drRem) < (remainLen)) and drRem or remainLen); + local pos = (dicPos - rep0) + (((dicPos) < (rep0)) and dicBufSize or 0); + + processedPos = processedPos + curLen; + + remainLen = remainLen - (curLen) ; + if (((pos + curLen) <= (dicBufSize))) then + assert(((dicPos) > (pos))); + assert(((curLen) > (0))); + repeat + + dic8[dicPos] = dic8[pos] -band- 0xFF; + dicPos=dicPos+1 + pos=pos+1 + curLen=curLen-1 + until not (((curLen) ~= (0))); + else + repeat + dic8[dicPos] = dic8[pos] -band- 0xFF; + dicPos=dicPos+1 + pos=pos+1 + if (((pos) == (dicBufSize))) then + pos = 0 ; + end + until not (((curLen) ~= (0))); + end + end + end + end + --print("drDicLimit2", drDicLimit2, "drBufLimit", drBufLimit, "dicPos", dicPos, "bufCur", bufCur) + until not (((dicPos) < (drDicLimit2)) and ((bufCur) < (drBufLimit))); + + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + if (((processedPos) >= (dicSize))) then + checkDicSize = dicSize; + end + LzmaDec_WriteRem(drDicLimit); + until not (((dicPos) < (drDicLimit)) and ((bufCur) < (drBufLimit)) and ((remainLen) < (274))); + + if (((remainLen) > (274))) then + remainLen = 274; + end + return 0; +end + +local function LzmaDec_TryDummy(tdCur, tdBufLimit) + local tdRange = range; + local tdCode = code; + local tdState = state; + local tdRes; + local tdProbIdx; + local tdBound; + local tdTtt; + local tdPosState = (processedPos) -band- ((1 -blshift- pb) - 1); + + + tdProbIdx = 0 + (tdState -blshift- (4)) + tdPosState ; + tdTtt = probs16[tdProbIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + local tdSymbol = 1; + tdRange = tdBound ; + tdProbIdx = 1846 ; + if (((checkDicSize) ~= (0)) or ((processedPos) ~= (0))) then + tdProbIdx = tdProbIdx + (768 * ((((processedPos) -band- ((1 -blshift- (lp)) - 1)) -blshift- lc) + (bitlib.rshift((dic8[(((dicPos) == (0)) and dicBufSize or dicPos) - 1]), (lcm8))))) ; + end + + if (((tdState) < (7))) then + repeat + tdTtt = probs16[tdProbIdx + tdSymbol] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdSymbol = (tdSymbol + tdSymbol); + else tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdSymbol = (tdSymbol + tdSymbol) + 1; + end + until not (((tdSymbol) < (0x100))); + else + local tdMatchByte = dic8[dicPos - rep0 + (((dicPos) < (rep0)) and dicBufSize or 0)]; + local tdMatchMask = 0x100; + repeat + local tdBit; + local tdProbLitIdx; + assert(tdMatchMask == 0 or tdMatchMask == 0x100); + tdMatchByte = tdMatchByte -blshift- 1 ; + tdBit = (tdMatchByte -band- tdMatchMask) ; + tdProbLitIdx = tdProbIdx + tdMatchMask + tdBit + tdSymbol ; + tdTtt = probs16[tdProbLitIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdSymbol = (tdSymbol + tdSymbol) ; + tdMatchMask = tdMatchMask -band- (bnot-tdBit) ; + else tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdSymbol = (tdSymbol + tdSymbol) + 1 ; + tdMatchMask = tdMatchMask -band- tdBit ; + end + until not (((tdSymbol) < (0x100))); + end + tdRes = 1 ; + else + local tdLen; + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdProbIdx = 192 + tdState ; + tdTtt = probs16[tdProbIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdState = 0 ; + tdProbIdx = 818 ; + tdRes = 2 ; + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdRes = 3 ; + tdProbIdx = 204 + tdState ; + tdTtt = probs16[tdProbIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdProbIdx = 240 + (tdState -blshift- (4)) + tdPosState ; + tdTtt = probs16[tdProbIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + return 3; + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + end + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdProbIdx = 216 + tdState ; + tdTtt = probs16[tdProbIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdProbIdx = 228 + tdState ; + tdTtt = probs16[tdProbIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + end + end + end + tdState = 12 ; + tdProbIdx = 1332 ; + end + do + local tdLimitSub; + local tdOffset; + local tdProbLenIdx = tdProbIdx + 0; + tdTtt = probs16[tdProbLenIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdProbLenIdx = tdProbIdx + 2 + (tdPosState -blshift- (3)) ; + tdOffset = 0 ; + tdLimitSub = 8 ; + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdProbLenIdx = tdProbIdx + 1 ; + tdTtt = probs16[tdProbLenIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdProbLenIdx = tdProbIdx + 130 + (tdPosState -blshift- (3)) ; + tdOffset = 8 ; + tdLimitSub = 8 ; + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdProbLenIdx = tdProbIdx + 258 ; + tdOffset = 8 + 8 ; + tdLimitSub = 256 ; + end + end + do + tdLen = 1 ; + repeat + tdTtt = probs16[tdProbLenIdx + tdLen] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdLen = (tdLen + tdLen); + else tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdLen = (tdLen + tdLen) + 1; + end + until not (((tdLen) < (tdLimitSub))); + tdLen = tdLen - tdLimitSub ; + end + tdLen = tdLen + tdOffset ; + end + + if (((tdState) < (4))) then + local tdPosSlot; + tdProbIdx = 432 + ((((tdLen) < (4)) and tdLen or 4 - 1) -blshift- (6)) ; + do + tdPosSlot = 1 ; + repeat + tdTtt = probs16[tdProbIdx + tdPosSlot] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdPosSlot = (tdPosSlot + tdPosSlot); + else tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdPosSlot = (tdPosSlot + tdPosSlot) + 1; + end + until not (((tdPosSlot) < (64))); + tdPosSlot = tdPosSlot - (64) ; + end + + assert((tdPosSlot <= 0x7fffffff) and ((tdPosSlot) < (64))); + if (((tdPosSlot) >= (4))) then + local tdDirectBitCount = (bitlib.rshift((tdPosSlot), (1))) - 1; + if (((tdPosSlot) < (14))) then + tdProbIdx = 688 + ((2 -bor- (tdPosSlot -band- 1)) -blshift- tdDirectBitCount) - tdPosSlot - 1 ; + else + tdDirectBitCount = tdDirectBitCount - 4 ; + repeat + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdRange = (bitlib.rshift((tdRange), 1)); + if (((tdCode - tdRange) -band- 0x80000000) == 0) then + tdCode = tdCode - tdRange; + end + tdDirectBitCount=tdDirectBitCount-1; + until not (((tdDirectBitCount) ~= (0))); + tdProbIdx = 802 ; + tdDirectBitCount = 4 ; + end + do + local tdI = 1; + repeat + tdTtt = probs16[tdProbIdx + tdI] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdI = (tdI + tdI); + else tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdI = (tdI + tdI) + 1; + end + tdDirectBitCount=tdDirectBitCount-1; + until not (((tdDirectBitCount) ~= (0))); + end + end + end + end + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + return tdRes; +end + +local function LzmaDec_InitDicAndState(idInitDic, idInitState) + + + needFlush = 1; + remainLen = 0; + tempBufSize = 0; + + if ((idInitDic ~= 0)) then + processedPos = 0; + checkDicSize = 0; + needInitLzma = 1; + end + if ((idInitState ~= 0)) then + needInitLzma = 1; + end +end + + + + + +local function LzmaDec_DecodeToDic(ddSrcLen) + + local decodeLimit = readCur + ddSrcLen; + local checkEndMarkNow; + local dummyRes; + + LzmaDec_WriteRem(dicBufSize); + + while (((remainLen) ~= (274))) do + if ((needFlush ~= 0)) then + + + + while (((decodeLimit) > (readCur)) and ((tempBufSize) < (5))) do + readBuf8[(6 + 65536 + 6) + tempBufSize] = readBuf8[readCur]; + tempBufSize=tempBufSize+1 + readCur=readCur+1 + end + if (((tempBufSize) < (5))) then + + + + + + end + if (((readBuf8[(6 + 65536 + 6)]) ~= (0))) then + --print("E") + return 1; + end + code = ((((readBuf8[(6 + 65536 + 6) + 1]) -blshift- 24) -bor- ((readBuf8[(6 + 65536 + 6) + 2]) -blshift- 16)) -bor- ((readBuf8[(6 + 65536 + 6) + 3]) -blshift- 8)) -bor- ((readBuf8[(6 + 65536 + 6) + 4])); + range = 0xffffffff; + needFlush = 0; + tempBufSize = 0; + end + + checkEndMarkNow = 0 ; + if (((dicPos) >= (dicBufSize))) then + if (((remainLen) == (0)) and ((code) == 0)) then + if (((readCur) ~= (decodeLimit))) then + return 18; + end + return 0 ; + end + if (((remainLen) ~= (0))) then + return 16; + end + checkEndMarkNow = 1 ; + end + + if ((needInitLzma ~= 0)) then + local numProbs = 1846 + ((768) -blshift- (lc + lp)); + for ddProbIdx = 0, numProbs-1, 1 do + probs16[ddProbIdx] = (bitlib.rshift((2048), (1))); + end + rep3 = 1; + rep2 = rep3; + rep1 = rep2; + rep0 = rep1; + state = 0; + needInitLzma = 0; + end + + if (((tempBufSize) == (0))) then + local bufLimit; + if (((decodeLimit - readCur) < (20)) or (checkEndMarkNow ~= 0)) then + dummyRes = LzmaDec_TryDummy(readCur, decodeLimit) ; + if (((dummyRes) == (0))) then + + tempBufSize = 0; + while (((readCur) ~= (decodeLimit))) do + readBuf8[(6 + 65536 + 6) + tempBufSize] = readBuf8[readCur]; + tempBufSize=tempBufSize+1; + readCur=readCur+1; + end + + + + if (((readCur) ~= (decodeLimit))) then + return 17; + end + return 17; + + end + if ((checkEndMarkNow ~= 0) and ((dummyRes) ~= (2))) then + return 16; + end + bufLimit = readCur ; + else + bufLimit = decodeLimit - 20 ; + end + bufCur = readCur; + if (((LzmaDec_DecodeReal2(dicBufSize, bufLimit)) ~= (0))) then + --print("F") + return 1; + end + readCur = bufCur; + else + local ddRem = tempBufSize; + local lookAhead = 0; + while (((ddRem) < (20)) and ((lookAhead) < (decodeLimit - readCur))) do + readBuf8[(6 + 65536 + 6) + ddRem] = readBuf8[readCur + lookAhead]; + ddRem=ddRem+1; + lookAhead=lookAhead+1; + end + tempBufSize = ddRem; + if (((ddRem) < (20)) or (checkEndMarkNow ~= 0)) then + dummyRes = LzmaDec_TryDummy((6 + 65536 + 6), (6 + 65536 + 6) + ddRem) ; + if (((dummyRes) == (0))) then + readCur = readCur + lookAhead; + + + + if (((readCur) ~= (decodeLimit))) then + return 17; + end + return 17; + + end + if ((checkEndMarkNow ~= 0) and ((dummyRes) ~= (2))) then + return 16; + end + end + + bufCur = (6 + 65536 + 6); + if (((LzmaDec_DecodeReal2(0, (6 + 65536 + 6))) ~= (0))) then + --print("G") + return 1; + end + lookAhead = lookAhead - ddRem - (bufCur - (6 + 65536 + 6)) ; + readCur = readCur + lookAhead; + tempBufSize = 0; + end + end + if (((code) ~= 0)) then + --print("H"); + return 1; + end + return 15; +end +local function Preread(prSize) + + + + local prPos = readEnd - readCur; + local prGot; + + assert(((prSize) <= ((6 + 65536 + 6)))); + if (((prPos) < (prSize))) then + if ((((6 + 65536 + 6) - readCur) < (prSize))) then + + + readEnd = 0 + while readEnd < prPos do + readBuf8[readEnd] = readBuf8[readCur + readEnd]; + readEnd=readEnd+1 + end + readCur = 0; + end + while (((prPos) < (prSize))) do + + + + + prGot = READ_FROM_STDIN_TO_ARY8(readBuf8, readEnd, prSize - prPos); + if (((prGot + 1) <= (1))) then + break; + end + readEnd = readEnd + prGot; + prPos = prPos + prGot ; + end + end + + return prPos; + + + + + +end + +local function IgnoreVarint() + while (((readBuf8[readCur]) >= (0x80))) do readCur = readCur + 1 end + readCur = readCur + 1 +end + +local function IgnoreZeroBytes(izCount) + + while ((izCount) ~= (0)) do + readCur=readCur+1 + if (((readBuf8[readCur-1]) ~= (0))) then + return 57; + end + izCount=izCount-1; + end + return 0; +end + +local function GetLE4(glPos) + --return ((readBuf8[glPos] -bor- (readBuf8[glPos + 1] -blshift- 8)) -bor- (readBuf8[glPos + 2] -blshift- 16)) -bor- (readBuf8[glPos + 3] -blshift- 24); + --print("glPos", glPos) + return bitlib.band(readBuf8[glPos], 0xff) + bitlib.blshift(bitlib.band(readBuf8[glPos+1], 0xff), 8) + bitlib.blshift(bitlib.band(readBuf8[glPos+2], 0xff), 16) + bit.blshift(bitlib.band(readBuf8[glPos+3], 0xff), 24) +end + + +local function InitDecode() + + + dicBufSize = 0; + needInitDic = 1; + needInitState = 1; + needInitProp = 1; + dicPos = 0; + LzmaDec_InitDicAndState(1, 1); +end + +local function InitProp(ipByte) + + if (((ipByte) >= (9 * 5 * 5))) then + return 68; + end + lc = ipByte % 9; + lcm8 = 8 - lc; + ipByte = math.floor(ipByte / 9) ; + pb = math.floor(ipByte / 5); + lp = ipByte % 5; + if (((lc + lp) > (4))) then + return 68; + end + needInitProp = 0; + return 0; +end + + +local function WriteFrom(wfDicPos) + + + local lastTime = os.epoch("utc") + + + while (((wfDicPos) ~= (dicPos))) do + local wfGot = WRITE_TO_STDOUT_FROM_ARY8(dic8, wfDicPos, dicPos - wfDicPos); + if (wfGot -band- 0x80000000) ~= 0 then + return 9; + end + wfDicPos = wfDicPos + wfGot ; + if textutils and os.epoch("utc") - lastTime > 3000 then + --write(",") + lastTime = os.epoch("utc") + os.queueEvent(os.pullEvent()) + end + end + + return 0; +end + + + + + + +local function DecompressXzOrLzma() + local checksumSize; + local bhf; + local dxRes; + + + + + if (((Preread(12 + 12 + 6)) < (12 + 12 + 6))) then + return 6; + end + + if (((readBuf8[0]) == (0xfd)) and ((readBuf8[1]) == (0x37)) and + ((readBuf8[2]) == (0x7a)) and ((readBuf8[3]) == (0x58)) and + ((readBuf8[4]) == (0x5a)) and ((readBuf8[5]) == (0)) and + ((readBuf8[6]) == (0))) then --print("xz") + elseif ( + ( + (readBuf8[readCur]) <= (225) + ) and ( + (readBuf8[readCur + 13]) == (0) + ) and ( + ( + ( + (function() bhf = GetLE4(readCur + 9); return bhf end)() + ) == 0 + ) or ( + (bnot-bhf) == 0 + ) + ) and ( + ( + (function() dicSize = GetLE4(readCur + 1); return dicSize end)() + ) >= ((4096)) + ) and ( + (dicSize) < bitlib.band((1610612736 + 1), 0x7fffffff) + ) + ) then + + local readBufUS; + local srcLen; + local fromDicPos; + InitDecode(); + + + + + + if ((((function() dxRes = InitProp(readBuf8[readCur]); return dxRes end)()) ~= (0))) then + return dxRes; + end + if (((bhf) == 0)) then + readBufUS = GetLE4(readCur + 5); + dicBufSize = readBufUS; + if (not ((readBufUS) < bitlib.band((1610612736 + 1), 0x7fffffff))) then + return 2; + end + else + readBufUS = bhf ; + + dicBufSize = 1610612736; + end + + readCur = readCur + 13; + + + + + + + + while ((((function() srcLen = Preread((6 + 65536 + 6)); return srcLen end)()) ~= (0))) do + fromDicPos = dicPos ; + dxRes = LzmaDec_DecodeToDic(srcLen) ; + + if (((readBufUS) < (dicPos))) then + dicPos = readBufUS; + end + if ((((function() dxRes = WriteFrom(fromDicPos); return dxRes end)()) ~= (0))) then + return dxRes; + end + if (((dxRes) == (15))) then + break; + end + if (((dxRes) ~= (17)) and ((dxRes) ~= (0))) then + return dxRes; + end + if (((dicPos - readBufUS) == 0)) then + break; + end + end + return 0; + else + return 51; + end + + checksumSize = readBuf8[readCur + 7]; + if (((checksumSize) == (0))) then + checksumSize = 1; + elseif (((checksumSize) == (1))) then + checksumSize = 4; + elseif (((checksumSize) == (4))) then + checksumSize = 8; + elseif (((checksumSize) == (10))) then + checksumSize = 32; + else return 60; + end + + readCur = readCur + 12; + while true do + + local blockSizePad = 3; + local bhs; + local bhs2; + local dicSizeProp; + local readAtBlock; + assert(((readEnd - readCur) >= (12))); + readAtBlock = readCur ; + readCur=readCur+1; + if ((((function() bhs = readBuf8[readCur-1]; return bhs end)()) == (0))) then + break; + end + + bhs = (bhs + 1) -blshift- 2; + + + if (((Preread(bhs)) < (bhs))) then + return 6; + end + readAtBlock = readCur ; + bhf = readBuf8[readCur] ; + --print("bhf", string.format("%x\n", bhf)) + readCur=readCur+1; + if (((bhf -band- 2) ~= (0))) then + return 53; + end + + if (((bhf -band- 20) ~= (0))) then + return 54; + end + if (((bhf -band- 64) ~= (0))) then + + IgnoreVarint(); + end + if (((bhf -band- 128) ~= (0))) then + + IgnoreVarint(); + end + if (((readBuf8[readCur]) ~= (0x21))) then + return 55; + end + readCur=readCur+1; + if (((readBuf8[readCur]) ~= (1))) then + return 56; + end + readCur=readCur+1; + dicSizeProp = readBuf8[readCur] ; + readCur=readCur+1; + if (((dicSizeProp) > (40))) then + return 61; + end + + + + if (((dicSizeProp) > (37))) then + return 62; + end + dicSize = (((2) -bor- ((dicSizeProp) -band- 1)) -blshift- (math.floor((dicSizeProp) / 2) + 11)); + assert(((dicSize) >= ((4096)))); + + + + + + bhs2 = readCur - readAtBlock + 5 ; + + if (((bhs2) > (bhs))) then + return 58; + end + if ((((function() dxRes = IgnoreZeroBytes(bhs - bhs2); return dxRes end)()) ~= (0))) then + return dxRes; + end + readCur = readCur + 4; + + + do + + local chunkUS; + local chunkCS; + local initDic; + InitDecode(); + + while true do + local control; + assert(((dicPos) == (dicBufSize))); + + + + if (((Preread(6)) < (6))) then + return 6; + end + control = readBuf8[readCur] ; + + if (((control) == (0))) then + + readCur=readCur+1; + break; + elseif ((((bitlib.band((control - 3), 0xff))) < (0x80 - 3))) then + return 59; + end + chunkUS = (readBuf8[readCur + 1] -blshift- 8) + readBuf8[readCur + 2] + 1 ; + --print("chunkUS", chunkUS, "readCur", readCur, "@1", readBuf8[readCur + 1], "@2", readBuf8[readCur + 2]) + if (((control) < (3))) then + initDic = (((control) == (1)) and 1 or 0); + chunkCS = chunkUS ; + readCur = readCur + 3; + + blockSizePad = blockSizePad - 3; + if ((initDic ~= 0)) then + needInitState = 1; + needInitProp = needInitState; + needInitDic = 0; + elseif ((needInitDic ~= 0)) then + --print("I") + return 1; + end + LzmaDec_InitDicAndState(initDic, 0); + else + local mode = ((bitlib.rshift(((control)), (5))) -band- 3); + local initState = (((mode) ~= (0)) and 1 or 0); + local isProp = ((((control -band- 64)) ~= (0)) and 1 or 0); + initDic = (((mode) == (3)) and 1 or 0); + chunkUS = chunkUS + ((control -band- 31) -blshift- 16) ; + chunkCS = (readBuf8[readCur + 3] -blshift- 8) + readBuf8[readCur + 4] + 1 ; + if ((isProp ~= 0)) then + if ((((function() dxRes = InitProp(readBuf8[readCur + 5]); return dxRes end)()) ~= (0))) then + return dxRes; + end + readCur=readCur+1; + blockSizePad=blockSizePad-1; + else + if ((needInitProp ~= 0)) then + return 67; + end + end + readCur = readCur + 5; + blockSizePad = blockSizePad - 5 ; + if (((initDic == 0) and (needInitDic ~= 0)) or ((initState == 0) and (needInitState ~= 0))) then + --print("J") + return 1; + end + LzmaDec_InitDicAndState(initDic, initState); + needInitDic = 0; + needInitState = 0; + end + assert(((dicPos) == (dicBufSize))); + dicBufSize = dicBufSize + chunkUS; + + if (((dicBufSize) > (1610612736))) then + return 2; + end + + + + + if (((Preread(chunkCS + 6)) < (chunkCS))) then + return 6; + end + + if (((control) < (0x80))) then + + while (((dicPos) ~= (dicBufSize))) do + dic8[dicPos] = readBuf8[readCur] -band- 0xFF; + dicPos=dicPos+1; + readCur=readCur+1; + end + if (((checkDicSize) == (0)) and ((dicSize - processedPos) <= (chunkUS))) then + checkDicSize = dicSize; + end + processedPos = processedPos + chunkUS; + else + + + if ((((function() dxRes = LzmaDec_DecodeToDic(chunkCS); return dxRes end)()) ~= (0))) then + return dxRes; + end + end + if (((dicPos) ~= (dicBufSize))) then + return 65; + end + if ((((function() dxRes = WriteFrom(dicPos - chunkUS); return dxRes end)()) ~= (0))) then + return dxRes; + end + blockSizePad = blockSizePad - chunkCS ; + + + + + end + end + + + + + if (((Preread(7 + 12 + 6)) < (7 + 12 + 6))) then + return 6; + end + + + if ((((function() dxRes = IgnoreZeroBytes(blockSizePad -band- 3); return dxRes end)()) ~= (0))) then + return dxRes; + end + readCur = readCur + checksumSize; + end + + return 0; +end + +local error_table = { + UNKNOWN_ERROR = -1, + OK = 0, + ERROR_DATA = 1, + ERROR_MEM = 2, + ERROR_CRC = 3, + ERROR_UNSUPPORTED = 4, + ERROR_PARAM = 5, + ERROR_INPUT_EOF = 6, + ERROR_OUTPUT_EOF = 7, + ERROR_READ = 8, + ERROR_WRITE = 9, + ERROR_FINISHED_WITH_MARK = 15, + ERROR_NOT_FINISHED = 16, + ERROR_NEEDS_MORE_INPUT = 17, + ERROR_CHUNK_NOT_CONSUMED = 18, + ERROR_NEEDS_MORE_INPUT_PARTIAL = 17, + ERROR_BAD_MAGIC = 51, + ERROR_BAD_STREAM_FLAGS = 52, + ERROR_UNSUPPORTED_FILTER_COUNT = 53, + ERROR_BAD_BLOCK_FLAGS = 54, + ERROR_UNSUPPORTED_FILTER_ID = 55, + ERROR_UNSUPPORTED_FILTER_PROPERTIES_SIZE = 56, + ERROR_BAD_PADDING = 57, + ERROR_BLOCK_HEADER_TOO_LONG = 58, + ERROR_BAD_CHUNK_CONTROL_BYTE = 59, + ERROR_BAD_CHECKSUM_TYPE = 60, + ERROR_BAD_DICTIONARY_SIZE = 61, + ERROR_UNSUPPORTED_DICTIONARY_SIZE = 62, + ERROR_FEED_CHUNK = 63, + ERROR_NOT_FINISHED_WITH_MARK = 64, + ERROR_BAD_DICPOS = 65, + ERROR_MISSING_INITPROP = 67, + ERROR_BAD_LCLPPB_PROP = 68, +} + +return { + --- Decompresses an XZ or LZMA file using file I/O. Both files will be closed after decompression finishes. + -- @param input The input file (path) to read from + -- @param output The output file (path) to write to + -- @return Whether the decompression succeeded + -- @return If failure, an error code describing the issue + DecompressXzOrLzmaFile = function(input, output) + if type(input) ~= "number" and type(input) ~= "string" and type(input)~="table" then error("bad argument #1 (expected string or file, got " .. type(input) .. ")", 2) end + if type(output) ~= "number" and type(output) ~= "string" and type(input)~="table" then error("bad argument #2 (expected string or file, got " .. type(output) .. ")", 2) end + str_input = nil + str_output = nil + if type(input) == "string" then + input = syscall.open(input, "r") + if input == nil then return false, -1 end + end + if type(output) == "string" then + output = syscall.open(output, "w") + if output == nil then return false, -1 end + end + ResetGlobals() + stdin=input + stdout=output + local ok, res = pcall(DecompressXzOrLzma) + syscall.close(input) + syscall.close(output) + if not ok then + if res then error(res .. "\n") end + return false, -1 + else return res == 0, res end + end, + + --- Decompresses XZ or LZMA data. + -- @param input The input data to decompress + -- @return The decompressed data, or nil if failure + -- @return If failure, an error code describing the issue + DecompressXzOrLzmaString = function(input) + if type(input) ~= "string" then error("bad argument #1 (expected string, got " .. type(input) .. ")", 2) end + str_input = input + str_output = "" + ResetGlobals() + local ok, res = pcall(DecompressXzOrLzma) + if not ok then + if res then error(res .. "\n") end + return -1 + elseif res == 0 then return str_output + elseif res == 53 and #str_output > 0 then return str_output, res + else return nil, res end + end, + + --- Translates error codes to a semi-understandable meaning. + -- @param code The error code + -- @return A string describing the error + GetError = function(code) for k,v in pairs(error_table) do if v == code then return k end end return nil end, + --- Error code table for your convenience + Errors = error_table, +} \ No newline at end of file diff --git a/build.py b/build.py index 1d08f6a..5715b27 100644 --- a/build.py +++ b/build.py @@ -27,6 +27,7 @@ import sys import shutil import argparse import subprocess +import json from pathlib import Path from typing import Union @@ -92,22 +93,24 @@ def process_root(src_root: Path, out_root: Path, minify: bool, micro: bool, arch for pkg_dir in sorted(src_root.iterdir()): if not pkg_dir.is_dir(): continue - + if pkg_dir.name[:18] == "Hyperion-firmware-": if pkg_dir.name != f"Hyperion-firmware-{arch}": if prod != True: continue + data_dir=pkg_dir / "data" + + if not data_dir.is_dir(): + continue + print(f"== Package: {pkg_dir.name} ==") - for src in sorted(pkg_dir.rglob("*")): + for src in sorted(data_dir.rglob("*")): if not src.is_file(): continue - rel = src.relative_to(pkg_dir) - - if rel.name=="$PKGCONFIG.ini": - continue + rel = src.relative_to(data_dir) dst = out_root / rel if prod: diff --git a/installers/HyperionOS-install-cct.lua b/installers/HyperionOS-install-cct.lua index 4eab2d7..58555d8 100644 --- a/installers/HyperionOS-install-cct.lua +++ b/installers/HyperionOS-install-cct.lua @@ -48,7 +48,6 @@ local function printTitle() print("DESCLAIMER: This will wipe your system on install...") term.write("Bspc: Back | Enter: execute | Tab: description") end -printTitle() local function pc(text, y, c) local x=(w/2)-#text/2 @@ -110,9 +109,7 @@ end local releases,page={},1 while true do - local handle=http.get("https://git.astronand.dev/api/v1/repos/Hyperion/HyperionOS/releases?page="..tostring(page).."&limit=1") - local raw=handle.readAll() - handle.close() + local raw=download("https://git.astronand.dev/api/v1/repos/Hyperion/HyperionOS/releases?page="..tostring(page).."&limit=1") if raw=="[]\n" then break end @@ -130,6 +127,8 @@ local function makePage(start, num) desc=release.body, color=release.prerelease and colors.orange or colors.white, func=function() + term.clear() + term.setCursorPos(1,1) local data=download("https://git.astronand.dev/Hyperion/HyperionOS/raw/tag/"..release.tag_name.."/Src/install.json") if not data then term.clear() @@ -158,7 +157,9 @@ local function makePage(start, num) return m end +printTitle() menu(makePage(1,5)) +if not exitall then error("Exited") end term.clear() term.setCursorPos(1,1) term.setTextColor(colors.white) @@ -187,8 +188,9 @@ local function delDir(dir) fs.delete(dir..list[i]) printc(colors.gray, "[ ", colors.red, " DELET ", colors.gray, " ] ", colors.white, dir..list[i]) end - sleep(.1) + sleep(.01) end + sleep(.15) end delDir("/") @@ -210,7 +212,9 @@ local function installdir(path, dir, pkg) else error("Uh Oh: unknown entrytype "..entry.path) end + sleep(.01) end + sleep(.15) end local function installpkg(pkg) diff --git a/misc/spm.lua b/misc/spm.lua new file mode 100644 index 0000000..bca07a8 --- /dev/null +++ b/misc/spm.lua @@ -0,0 +1,55 @@ +local cloptions = { + a = false, + h = false, + l = false, + help = false, +} +local inpArgs = { ... } +local args = {} + +for _, v in pairs(inpArgs) do + if v:sub(1, 2) == "--" then + local opt = v:sub(3) + if cloptions[opt] == nil then + print("spm: unrecognized option '" .. v .. "'.") + print("try 'spm --help' for more information.") + return + end + cloptions[opt] = true + elseif v:sub(1, 1) == "-" then + for i = 2, #v do + local opt = v:sub(i, i) + if cloptions[opt] == nil then + print("spm: invalid option '-" .. opt .. "'.") + print("try 'spm --help' for more information.") + return + end + cloptions[opt] = true + end + else + table.insert(args, v) + end +end + +local http=http or require("http") +local json=json or require("json") +local xz =xz or require("xz") + +if cloptions.help then + print("Usage: spm [COMMAND] [OPTION] [packages]") + print("The Simple package Mannager.") + print("") + print("Commands:") + print(" remove Remove package(s)") + print(" update Updates package(s)") + print(" install Install package(s)") + print(" sync Syncs local registry with servers") + print("") + print("Options:") + print(" --help display this help and exit") + return +end + +local function getustar() + +end \ No newline at end of file diff --git a/misc/xz b/misc/xz new file mode 100644 index 0000000..6254bfc --- /dev/null +++ b/misc/xz @@ -0,0 +1,1973 @@ +--[[ + XZ/LZMA decompressor ported from https://github.com/pts/muxzcat + Licensed under GNU GPL 2.0 or later + This should work under all Lua 5.1+ + To use: + muxzcat.DecompressXzOrLzmaFile(input, output) will read an XZ/LZMA file from input (FILE* or path) and write the result to output (FILE* or path) + muxzcat.DecompressXzOrLzmaString(input) will decompress a loaded XZ/LZMA file and returns the result + muxzcat.GetError(num) will return a string representation for an error code + muxzcat.ErrorCodes is a table that reverses GetError() + Written by pts@fazekas.hu at Sat Feb 2 13:28:42 CET 2019 + Ported to Lua by JackMacWindows +]] + +local bitlib +if bit32 ~= nil then bitlib = bit32 +elseif pcall(require, "bit32") then bitlib = require "bit32" +elseif pcall(require, "bit") then bitlib = require "bit" +elseif bit ~= nil then bitlib = bit +else + --[[--------------- + LuaBit v0.4 + ------------------- + a bitwise operation lib for lua. + + http: + + How to use: + ------------------- + bit.bnot(n) -- bitwise not (~n) + bit.band(m, n) -- bitwise and (m & n) + bit.bor(m, n) -- bitwise or (m | n) + bit.bxor(m, n) -- bitwise xor (m ^ n) + bit.brshift(n, bits) -- right shift (n >> bits) + bit.blshift(n, bits) -- left shift (n << bits) + bit.blogic_rshift(n, bits) -- logic right shift(zero fill >>>) + + Please note that bit.brshift and bit.blshift only support number within + 32 bits. + + 2 utility functions are provided too: + bit.tobits(n) -- convert n into a bit table(which is a 1/0 sequence) + -- high bits first + bit.tonumb(bit_tbl) -- convert a bit table into a number + ------------------- + + Under the MIT license. + + copyright(c) 2006~2007 hanzhao (abrash_han@hotmail.com) + --]]--------------- + ------------------------ + -- bit lib implementions + + local function check_int(n) + -- checking not float + if(n - math.floor(n) > 0) then + error("trying to use bitwise operation on non-integer!") + end + end + + local function to_bits(n) + check_int(n) + if(n < 0) then + -- negative + return to_bits(bitlib.bnot(math.abs(n)) + 1) + end + -- to bits table + local tbl = {} + local cnt = 1 + while (n > 0) do + local last = math.mod(n,2) + if(last == 1) then + tbl[cnt] = 1 + else + tbl[cnt] = 0 + end + n = (n-last)/2 + cnt = cnt + 1 + end + + return tbl + end + + local function tbl_to_number(tbl) + local n = table.getn(tbl) + + local rslt = 0 + local power = 1 + for i = 1, n do + rslt = rslt + tbl[i]*power + power = power*2 + end + + return rslt + end + + local function expand(tbl_m, tbl_n) + local big = {} + local small = {} + if(table.getn(tbl_m) > table.getn(tbl_n)) then + big = tbl_m + small = tbl_n + else + big = tbl_n + small = tbl_m + end + -- expand small + for i = table.getn(small) + 1, table.getn(big) do + small[i] = 0 + end + + end + + local function bit_or(m, n) + local tbl_m = to_bits(m) + local tbl_n = to_bits(n) + expand(tbl_m, tbl_n) + + local tbl = {} + local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n)) + for i = 1, rslt do + if(tbl_m[i]== 0 and tbl_n[i] == 0) then + tbl[i] = 0 + else + tbl[i] = 1 + end + end + + return tbl_to_number(tbl) + end + + local function bit_and(m, n) + local tbl_m = to_bits(m) + local tbl_n = to_bits(n) + expand(tbl_m, tbl_n) + + local tbl = {} + local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n)) + for i = 1, rslt do + if(tbl_m[i]== 0 or tbl_n[i] == 0) then + tbl[i] = 0 + else + tbl[i] = 1 + end + end + + return tbl_to_number(tbl) + end + + local function bit_not(n) + + local tbl = to_bits(n) + local size = math.max(table.getn(tbl), 32) + for i = 1, size do + if(tbl[i] == 1) then + tbl[i] = 0 + else + tbl[i] = 1 + end + end + return tbl_to_number(tbl) + end + + local function bit_xor(m, n) + local tbl_m = to_bits(m) + local tbl_n = to_bits(n) + expand(tbl_m, tbl_n) + + local tbl = {} + local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n)) + for i = 1, rslt do + if(tbl_m[i] ~= tbl_n[i]) then + tbl[i] = 1 + else + tbl[i] = 0 + end + end + + --table.foreach(tbl, --print) + + return tbl_to_number(tbl) + end + + local function bit_rshift(n, bits) + check_int(n) + + local high_bit = 0 + if(n < 0) then + -- negative + n = bit_not(math.abs(n)) + 1 + high_bit = 2147483648 -- 0x80000000 + end + + for i=1, bits do + n = n/2 + n = bit_or(math.floor(n), high_bit) + end + return math.floor(n) + end + + -- logic rightshift assures zero filling shift + local function bit_logic_rshift(n, bits) + check_int(n) + if(n < 0) then + -- negative + n = bit_not(math.abs(n)) + 1 + end + for i=1, bits do + n = n/2 + end + return math.floor(n) + end + + local function bit_lshift(n, bits) + check_int(n) + + if(n < 0) then + -- negative + n = bit_not(math.abs(n)) + 1 + end + + for i=1, bits do + n = n*2 + end + return bit_and(n, 4294967295) -- 0xFFFFFFFF + end + + -------------------- + -- bit lib interface + + bitlib = { + -- bit operations + bnot = bit_not, + band = bit_and, + bor = bit_or, + bxor = bit_xor, + brshift = bit_rshift, + blshift = bit_lshift, + blogic_rshift = bit_logic_rshift, + } +end +if bitlib.blogic_rshift then + bitlib = { + arshift = bitlib.brshift, + band = bitlib.band, + bnot = bitlib.bnot, + bor = bitlib.bor, + btest = function(a, b) return bitlib.band(a, b) ~= 0 end, + bxor = bitlib.bxor, + lshift = bitlib.blshift, + rshift = bitlib.blogic_rshift + } +end + +local band = {} +local bor = {} +local bxor = {} +local bnot = {} +local blshift = {} +local brshift = {} + +setmetatable(band, {__sub = function(lhs) + local mt = {lhs, __sub = function(self, b) return bitlib.band(self[1], b) end} + return setmetatable(mt, mt) +end}) + +setmetatable(bor, {__sub = function(lhs) + local mt = {lhs, __sub = function(self, b) return bitlib.bor(self[1], b) end} + return setmetatable(mt, mt) +end}) + +setmetatable(bxor, {__sub = function(lhs) + local mt = {lhs, __sub = function(self, b) return bitlib.bxor(self[1], b) end} + return setmetatable(mt, mt) +end}) + +setmetatable(blshift, {__sub = function(lhs) + local mt = {lhs, __sub = function(self, b) return bitlib.lshift(self[1], b) end} + return setmetatable(mt, mt) +end}) + +setmetatable(brshift, {__sub = function(lhs) + local mt = {lhs, __sub = function(self, b) return bitlib.rshift(self[1], b) end} + return setmetatable(mt, mt) +end}) + +setmetatable(bnot, {__sub = function(_, rhs) return bitlib.bnot(rhs) end}) + +local str_input, str_output + +local function writeTableSeq(tab, i, n, ...) if n ~= nil then tab[i] = n return writeTableSeq(tab, i+1, ...) end end + +local stdin=0 +local stdout=1 + +local function READ_FROM_STDIN_TO_ARY8(a, fromIdx, size) + local str + if str_input then + str, str_input = str_input:sub(1, size), str_input:sub(size+1) + for i = 1, #str, 256 do writeTableSeq(a, fromIdx + i - 1, str:byte(i, i + 256)) end + return #str + else + str = syscall.read(stdin,size) + for i = 1, #str, 256 do writeTableSeq(a, fromIdx + i - 1, str:byte(i, i + 256)) end + --assert(#a - fromIdx == #str - 1, (#a - fromIdx) .. ", " .. #str .. ", " .. size) + return #str + end +end + +local function readTableSeq(tab, i, j) if i == j then return tab[i] elseif i > j then return nil else return tab[i], readTableSeq(tab, i+1, j) end end + +local function WRITE_TO_STDOUT_FROM_ARY8(a, fromIdx, size) + if str_output then + for i = fromIdx, fromIdx + size - 1, 256 do str_output = str_output .. string.char(readTableSeq(a, i, math.min(fromIdx + size - 1, i + 255))) end + return size + else + for i = 1, size, 256 do syscall.write(stdout,string.char(readTableSeq(a, i+fromIdx-1, math.min(fromIdx + size - 1, i + fromIdx + 254)))) end + return size + end +end + +local bufCur = 0; +local dicSize = 0; +local range = 0; +local code = 0; +local dicPos = 0; +local dicBufSize = 0; +local processedPos = 0; +local checkDicSize = 0; +local state = 0; +local rep0 = 1; +local rep1 = 1; +local rep2 = 1; +local rep3 = 1; +local remainLen = 0; +local tempBufSize = 0; +local readCur = 0; +local readEnd = 0; +local needFlush = 0; +local needInitLzma = 0; +local needInitDic = 0; +local needInitState = 0; +local needInitProp = 0; +local lc = 0; +local lp = 0; +local pb = 0; +local lcm8 = 0; +local _probs16 = {} +local probs16 = setmetatable({}, {__index = function(_, idx) return _probs16[idx] --[[-band- 0xFFFF]] end, __newindex = function(_, idx, val) _probs16[idx] = val -band- 0xFFFF end}); +local _readBuf8 = {} +local readBuf8 = setmetatable({}, {__index = function(_, idx) return _readBuf8[idx] --[[-band- 0xFF]] end, __newindex = function(_, idx, val) _readBuf8[idx] = val -band- 0xFF end}); +local _dic8 = {} +local dic8 = setmetatable({}, {__index = function(_, idx) return _dic8[idx] --[[-band- 0xFF]] end, __newindex = function(_, idx, val) _dic8[idx] = val -band- 0xFF end}); + +local function ResetGlobals() + bufCur = 0; + dicSize = 0; + range = 0; + code = 0; + dicPos = 0; + dicBufSize = 0; + processedPos = 0; + checkDicSize = 0; + state = 0; + rep0 = 1; + rep1 = 1; + rep2 = 1; + rep3 = 1; + remainLen = 0; + tempBufSize = 0; + readCur = 0; + readEnd = 0; + needFlush = 0; + needInitLzma = 0; + needInitDic = 0; + needInitState = 0; + needInitProp = 0; + lc = 0; + lp = 0; + pb = 0; + lcm8 = 0; + _probs16 = {} + _readBuf8 = {} + _dic8 = {} + stdin=0 + stdout=1 +end + +local function LzmaDec_WriteRem(wrDicLimit) + + if (((remainLen) ~= (0)) and ((remainLen) < (274))) then + local wrLen = remainLen; + if (((wrDicLimit - dicPos) < (wrLen))) then + wrLen = wrDicLimit - dicPos ; + end + if (((checkDicSize) == (0)) and ((dicSize - processedPos) <= (wrLen))) then + checkDicSize = dicSize; + end + processedPos = processedPos + wrLen; + remainLen = remainLen - wrLen; + while (((wrLen) ~= (0))) do + wrLen=wrLen-1; + dic8[dicPos] = dic8[(dicPos - rep0) + (((dicPos) < (rep0)) and dicBufSize or 0)] -band- 0xFF; + dicPos=dicPos+1; + end + end +end + + +local function LzmaDec_DecodeReal2(drDicLimit, drBufLimit) + local pbMask = ((1) -blshift- (pb)) - 1; + local lpMask = ((1) -blshift- (lp)) - 1; + local drI = 0; + local lastTime + if textutils then + os.queueEvent("nosleep") + lastTime = os.epoch("utc") + end + + repeat + local drDicLimit2 = (((checkDicSize) == (0)) and ((dicSize - processedPos) < (drDicLimit - dicPos))) and (dicPos + (dicSize - processedPos)) or drDicLimit; + --print("drDicLimit2", drDicLimit2, "checkDicSize", checkDicSize, "dicSize", dicSize, "processedPos", processedPos, "drDicLimit", drDicLimit, "dicPos", dicPos) + remainLen = 0; + repeat + local drProbIdx = 0; + local drBound = 0; + local drTtt = 0; + local distance = 0; + local drPosState = processedPos -band- pbMask; + if textutils and os.epoch("utc") - lastTime > 3000 then + --write(".") + lastTime = os.epoch("utc") + os.queueEvent(os.pullEvent()) + end + --print(rep0, rep1, rep2, rep3) + drProbIdx = 0 + (state -blshift- (4)) + drPosState ; + drTtt = probs16[drProbIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur = bufCur + 1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + local drSymbol = 0; + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + range = (drBound) ; + probs16[drProbIdx] = drTtt + ((bitlib.rshift((2048 - drTtt), (5)))); + drProbIdx = 1846 ; + if (((checkDicSize) ~= (0)) or ((processedPos) ~= (0))) then + drProbIdx = drProbIdx + (768 * (((processedPos -band- lpMask) -blshift- lc) + (bitlib.rshift((dic8[(((dicPos) == (0)) and dicBufSize or dicPos) - 1]), (lcm8))))) ; + end + if (((state) < (7))) then + state = state - ((((state) < (4))) and state or 3); + drSymbol = 1 ; + repeat + drTtt = probs16[drProbIdx + drSymbol] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = ((bitlib.rshift((range), 11))) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx + drSymbol] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drSymbol = (drSymbol + drSymbol); + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx + drSymbol] = drTtt - (bitlib.rshift((drTtt), (5))); + drSymbol = (drSymbol + drSymbol) + 1; + end + until not (((drSymbol) < (0x100))) + else + local drMatchByte = dic8[(dicPos - rep0) + (((dicPos) < (rep0)) and dicBufSize or 0)]; + local drMatchMask = 0x100; + state = state - (((state) < (10)) and 3 or 6); + drSymbol = 1 ; + repeat + local drBit; + local drProbLitIdx; + assert(drMatchMask == 0 or drMatchMask == 0x100); + drMatchByte = drMatchByte -blshift- 1 ; + drBit = (drMatchByte -band- drMatchMask) ; + drProbLitIdx = drProbIdx + drMatchMask + drBit + drSymbol ; + drTtt = probs16[drProbLitIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbLitIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drSymbol = (drSymbol + drSymbol) ; + drMatchMask = drMatchMask -band- (bnot-drBit) ; + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbLitIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + drSymbol = (drSymbol + drSymbol) + 1 ; + drMatchMask = drMatchMask -band- drBit ; + end + until not (((drSymbol) < (0x100))); + end + dic8[dicPos] = drSymbol -band- 0xFF; + dicPos=dicPos+1; + processedPos=processedPos+1; + --print("continue2") + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + drProbIdx = 192 + state ; + drTtt = probs16[drProbIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + local shouldContinue = true + if (((code) < (drBound))) then + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + range = (drBound) ; + probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + state = state + 12; + drProbIdx = 818 ; + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + if (((checkDicSize) == (0)) and ((processedPos) == (0))) then + --print("A") + return 1; + end + drProbIdx = 204 + state ; + drTtt = probs16[drProbIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + range = (drBound) ; + probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drProbIdx = 240 + (state -blshift- (4)) + drPosState ; + drTtt = probs16[drProbIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + dic8[dicPos] = dic8[(dicPos - rep0) + (((dicPos) < (rep0)) and dicBufSize or 0)] -band- 0xFF; + dicPos=dicPos+1; + processedPos=processedPos+1; + state = ((state) < (7)) and 9 or 11; + --print("continue") + shouldContinue = false + end + if shouldContinue then + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + end + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + drProbIdx = 216 + state ; + drTtt = probs16[drProbIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + distance = rep1 ; + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + drProbIdx = 228 + state ; + drTtt = probs16[drProbIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + distance = rep2 ; + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + distance = rep3 ; + rep3 = rep2; + end + rep2 = rep1; + end + rep1 = rep0; + rep0 = distance; + end + if shouldContinue then + state = ((state) < (7)) and 8 or 11; + drProbIdx = 1332 ; + end + end + if shouldContinue then + --print(distance) + do + local drLimitSub; + local drOffset; + local drProbLenIdx = drProbIdx + 0; + drTtt = probs16[drProbLenIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + range = (drBound) ; + probs16[drProbLenIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drProbLenIdx = drProbIdx + 2 + (drPosState -blshift- (3)) ; + drOffset = 0 ; + drLimitSub = (8) ; + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbLenIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + drProbLenIdx = drProbIdx + 1 ; + drTtt = probs16[drProbLenIdx] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + range = (drBound) ; + probs16[drProbLenIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drProbLenIdx = drProbIdx + 130 + (drPosState -blshift- (3)) ; + drOffset = 8 ; + drLimitSub = 8 ; + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbLenIdx] = drTtt - (bitlib.rshift((drTtt), (5))); + drProbLenIdx = drProbIdx + 258 ; + drOffset = 8 + 8 ; + drLimitSub = 256 ; + end + end + do + remainLen = (1) ; + repeat + drTtt = probs16[(drProbLenIdx + remainLen)] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[(drProbLenIdx + remainLen)] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + remainLen = ((remainLen + remainLen)); + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[(drProbLenIdx + remainLen)] = drTtt - (bitlib.rshift((drTtt), (5))); + remainLen = ((remainLen + remainLen) + 1); + end + until not (((remainLen) < (drLimitSub))); + remainLen = remainLen - (drLimitSub) ; + end + remainLen = remainLen + (drOffset) ; + end + + if (((state) >= (12))) then + drProbIdx = 432 + ((((remainLen) < (4)) and remainLen or 4 - 1) -blshift- (6)) ; + do + distance = 1 ; + repeat + drTtt = probs16[(drProbIdx + distance)] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[(drProbIdx + distance)] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + distance = (distance + distance); + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[(drProbIdx + distance)] = drTtt - (bitlib.rshift((drTtt), (5))); + distance = (distance + distance) + 1; + end + until not (((distance) < ((64)))); + distance = distance - (64) ; + end + assert((distance <= 0x7fffffff) and ((distance) < (64))); + if (((distance) >= (4))) then + local drPosSlot = distance; + local drDirectBitCount = (bitlib.rshift((distance), (1))) - 1; + distance = (2 -bor- (distance -band- 1)) ; + if (((drPosSlot) < (14))) then + distance = distance -blshift- drDirectBitCount ; + drProbIdx = 688 + distance - drPosSlot - 1 ; + do + local mask = 1; + drI = 1; + repeat + drTtt = probs16[drProbIdx + drI] ; + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drI = (drI + drI); + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); + drI = (drI + drI) + 1 ; + distance = distance -bor- mask ; + end + mask = mask -blshift- 1 ; + drDirectBitCount = drDirectBitCount - 1 + until not (((drDirectBitCount) ~= (0))); + end + else + drDirectBitCount = drDirectBitCount - 4 ; + repeat + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + + range = ((bitlib.rshift((range), 1))); + if (((code - range) -band- 0x80000000 ~= 0)) then + distance = distance -blshift- 1; + else + code = code - (range); + + distance = (distance -blshift- 1) + 1; + end + drDirectBitCount = drDirectBitCount-1; + until not (((drDirectBitCount) ~= (0))); + drProbIdx = 802 ; + distance = distance -blshift- 4 ; + do + drI = 1; + drTtt = probs16[drProbIdx + drI]; + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drI = (drI + drI); + else + range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); + drI = (drI + drI) + 1 ; + distance = distance -bor- 1 ; + end + drTtt = probs16[drProbIdx + drI]; + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drI = (drI + drI); + else range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); + drI = (drI + drI) + 1 ; + distance = distance -bor- 2 ; + end + drTtt = probs16[drProbIdx + drI]; + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drI = (drI + drI); + else range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); + drI = (drI + drI) + 1 ; + distance = distance -bor- 4 ; + end + drTtt = probs16[drProbIdx + drI]; + assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + drBound = (bitlib.rshift((range), 11)) * drTtt ; + if (((code) < (drBound))) then + range = (drBound) ; + probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); + drI = (drI + drI); + else range = range - (drBound) ; + code = code - (drBound) ; + probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); + drI = (drI + drI) + 1 ; + distance = distance -bor- 8 ; + end + end + if (((bnot-distance) == 0)) then + remainLen = remainLen + (274) ; + state = state - 12; + --print("break") + break; + end + end + end + + assert((distance <= 0x7fffffff) and ((distance) <= (1610612736))); + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + rep0 = distance + 1; + if (((checkDicSize) == (0))) then + if (((distance) >= (processedPos))) then + --print("B") + return 1; + end + else + if (((distance) >= (checkDicSize))) then + --print("C") + return 1; + end + end + state = ((state) < (12 + 7)) and 7 or 7 + 3; + end + + remainLen = remainLen + (2) ; + + if (((drDicLimit2) == (dicPos))) then + --print("D") + return 1; + end + do + local drRem = drDicLimit2 - dicPos; + local curLen = (((drRem) < (remainLen)) and drRem or remainLen); + local pos = (dicPos - rep0) + (((dicPos) < (rep0)) and dicBufSize or 0); + + processedPos = processedPos + curLen; + + remainLen = remainLen - (curLen) ; + if (((pos + curLen) <= (dicBufSize))) then + assert(((dicPos) > (pos))); + assert(((curLen) > (0))); + repeat + + dic8[dicPos] = dic8[pos] -band- 0xFF; + dicPos=dicPos+1 + pos=pos+1 + curLen=curLen-1 + until not (((curLen) ~= (0))); + else + repeat + dic8[dicPos] = dic8[pos] -band- 0xFF; + dicPos=dicPos+1 + pos=pos+1 + if (((pos) == (dicBufSize))) then + pos = 0 ; + end + until not (((curLen) ~= (0))); + end + end + end + end + --print("drDicLimit2", drDicLimit2, "drBufLimit", drBufLimit, "dicPos", dicPos, "bufCur", bufCur) + until not (((dicPos) < (drDicLimit2)) and ((bufCur) < (drBufLimit))); + + if (((range) < (16777216))) then + range = range -blshift- (8) ; + code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; + bufCur=bufCur+1; + end + if (((processedPos) >= (dicSize))) then + checkDicSize = dicSize; + end + LzmaDec_WriteRem(drDicLimit); + until not (((dicPos) < (drDicLimit)) and ((bufCur) < (drBufLimit)) and ((remainLen) < (274))); + + if (((remainLen) > (274))) then + remainLen = 274; + end + return 0; +end + +local function LzmaDec_TryDummy(tdCur, tdBufLimit) + local tdRange = range; + local tdCode = code; + local tdState = state; + local tdRes; + local tdProbIdx; + local tdBound; + local tdTtt; + local tdPosState = (processedPos) -band- ((1 -blshift- pb) - 1); + + + tdProbIdx = 0 + (tdState -blshift- (4)) + tdPosState ; + tdTtt = probs16[tdProbIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + local tdSymbol = 1; + tdRange = tdBound ; + tdProbIdx = 1846 ; + if (((checkDicSize) ~= (0)) or ((processedPos) ~= (0))) then + tdProbIdx = tdProbIdx + (768 * ((((processedPos) -band- ((1 -blshift- (lp)) - 1)) -blshift- lc) + (bitlib.rshift((dic8[(((dicPos) == (0)) and dicBufSize or dicPos) - 1]), (lcm8))))) ; + end + + if (((tdState) < (7))) then + repeat + tdTtt = probs16[tdProbIdx + tdSymbol] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdSymbol = (tdSymbol + tdSymbol); + else tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdSymbol = (tdSymbol + tdSymbol) + 1; + end + until not (((tdSymbol) < (0x100))); + else + local tdMatchByte = dic8[dicPos - rep0 + (((dicPos) < (rep0)) and dicBufSize or 0)]; + local tdMatchMask = 0x100; + repeat + local tdBit; + local tdProbLitIdx; + assert(tdMatchMask == 0 or tdMatchMask == 0x100); + tdMatchByte = tdMatchByte -blshift- 1 ; + tdBit = (tdMatchByte -band- tdMatchMask) ; + tdProbLitIdx = tdProbIdx + tdMatchMask + tdBit + tdSymbol ; + tdTtt = probs16[tdProbLitIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdSymbol = (tdSymbol + tdSymbol) ; + tdMatchMask = tdMatchMask -band- (bnot-tdBit) ; + else tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdSymbol = (tdSymbol + tdSymbol) + 1 ; + tdMatchMask = tdMatchMask -band- tdBit ; + end + until not (((tdSymbol) < (0x100))); + end + tdRes = 1 ; + else + local tdLen; + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdProbIdx = 192 + tdState ; + tdTtt = probs16[tdProbIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdState = 0 ; + tdProbIdx = 818 ; + tdRes = 2 ; + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdRes = 3 ; + tdProbIdx = 204 + tdState ; + tdTtt = probs16[tdProbIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdProbIdx = 240 + (tdState -blshift- (4)) + tdPosState ; + tdTtt = probs16[tdProbIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + return 3; + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + end + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdProbIdx = 216 + tdState ; + tdTtt = probs16[tdProbIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdProbIdx = 228 + tdState ; + tdTtt = probs16[tdProbIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + end + end + end + tdState = 12 ; + tdProbIdx = 1332 ; + end + do + local tdLimitSub; + local tdOffset; + local tdProbLenIdx = tdProbIdx + 0; + tdTtt = probs16[tdProbLenIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdProbLenIdx = tdProbIdx + 2 + (tdPosState -blshift- (3)) ; + tdOffset = 0 ; + tdLimitSub = 8 ; + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdProbLenIdx = tdProbIdx + 1 ; + tdTtt = probs16[tdProbLenIdx] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdProbLenIdx = tdProbIdx + 130 + (tdPosState -blshift- (3)) ; + tdOffset = 8 ; + tdLimitSub = 8 ; + else + tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdProbLenIdx = tdProbIdx + 258 ; + tdOffset = 8 + 8 ; + tdLimitSub = 256 ; + end + end + do + tdLen = 1 ; + repeat + tdTtt = probs16[tdProbLenIdx + tdLen] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdLen = (tdLen + tdLen); + else tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdLen = (tdLen + tdLen) + 1; + end + until not (((tdLen) < (tdLimitSub))); + tdLen = tdLen - tdLimitSub ; + end + tdLen = tdLen + tdOffset ; + end + + if (((tdState) < (4))) then + local tdPosSlot; + tdProbIdx = 432 + ((((tdLen) < (4)) and tdLen or 4 - 1) -blshift- (6)) ; + do + tdPosSlot = 1 ; + repeat + tdTtt = probs16[tdProbIdx + tdPosSlot] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdPosSlot = (tdPosSlot + tdPosSlot); + else tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdPosSlot = (tdPosSlot + tdPosSlot) + 1; + end + until not (((tdPosSlot) < (64))); + tdPosSlot = tdPosSlot - (64) ; + end + + assert((tdPosSlot <= 0x7fffffff) and ((tdPosSlot) < (64))); + if (((tdPosSlot) >= (4))) then + local tdDirectBitCount = (bitlib.rshift((tdPosSlot), (1))) - 1; + if (((tdPosSlot) < (14))) then + tdProbIdx = 688 + ((2 -bor- (tdPosSlot -band- 1)) -blshift- tdDirectBitCount) - tdPosSlot - 1 ; + else + tdDirectBitCount = tdDirectBitCount - 4 ; + repeat + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdRange = (bitlib.rshift((tdRange), 1)); + if (((tdCode - tdRange) -band- 0x80000000) == 0) then + tdCode = tdCode - tdRange; + end + tdDirectBitCount=tdDirectBitCount-1; + until not (((tdDirectBitCount) ~= (0))); + tdProbIdx = 802 ; + tdDirectBitCount = 4 ; + end + do + local tdI = 1; + repeat + tdTtt = probs16[tdProbIdx + tdI] ; + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; + if (((tdCode) < (tdBound))) then + tdRange = tdBound ; + tdI = (tdI + tdI); + else tdRange = tdRange - tdBound ; + tdCode = tdCode - tdBound ; + tdI = (tdI + tdI) + 1; + end + tdDirectBitCount=tdDirectBitCount-1; + until not (((tdDirectBitCount) ~= (0))); + end + end + end + end + if (((tdRange) < (16777216))) then + if (((tdCur) >= (tdBufLimit))) then + return 0; + end + tdRange = tdRange -blshift- 8 ; + tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; + tdCur=tdCur+1; + end + return tdRes; +end + +local function LzmaDec_InitDicAndState(idInitDic, idInitState) + + + needFlush = 1; + remainLen = 0; + tempBufSize = 0; + + if ((idInitDic ~= 0)) then + processedPos = 0; + checkDicSize = 0; + needInitLzma = 1; + end + if ((idInitState ~= 0)) then + needInitLzma = 1; + end +end + + + + + +local function LzmaDec_DecodeToDic(ddSrcLen) + + local decodeLimit = readCur + ddSrcLen; + local checkEndMarkNow; + local dummyRes; + + LzmaDec_WriteRem(dicBufSize); + + while (((remainLen) ~= (274))) do + if ((needFlush ~= 0)) then + + + + while (((decodeLimit) > (readCur)) and ((tempBufSize) < (5))) do + readBuf8[(6 + 65536 + 6) + tempBufSize] = readBuf8[readCur]; + tempBufSize=tempBufSize+1 + readCur=readCur+1 + end + if (((tempBufSize) < (5))) then + + + + + + end + if (((readBuf8[(6 + 65536 + 6)]) ~= (0))) then + --print("E") + return 1; + end + code = ((((readBuf8[(6 + 65536 + 6) + 1]) -blshift- 24) -bor- ((readBuf8[(6 + 65536 + 6) + 2]) -blshift- 16)) -bor- ((readBuf8[(6 + 65536 + 6) + 3]) -blshift- 8)) -bor- ((readBuf8[(6 + 65536 + 6) + 4])); + range = 0xffffffff; + needFlush = 0; + tempBufSize = 0; + end + + checkEndMarkNow = 0 ; + if (((dicPos) >= (dicBufSize))) then + if (((remainLen) == (0)) and ((code) == 0)) then + if (((readCur) ~= (decodeLimit))) then + return 18; + end + return 0 ; + end + if (((remainLen) ~= (0))) then + return 16; + end + checkEndMarkNow = 1 ; + end + + if ((needInitLzma ~= 0)) then + local numProbs = 1846 + ((768) -blshift- (lc + lp)); + for ddProbIdx = 0, numProbs-1, 1 do + probs16[ddProbIdx] = (bitlib.rshift((2048), (1))); + end + rep3 = 1; + rep2 = rep3; + rep1 = rep2; + rep0 = rep1; + state = 0; + needInitLzma = 0; + end + + if (((tempBufSize) == (0))) then + local bufLimit; + if (((decodeLimit - readCur) < (20)) or (checkEndMarkNow ~= 0)) then + dummyRes = LzmaDec_TryDummy(readCur, decodeLimit) ; + if (((dummyRes) == (0))) then + + tempBufSize = 0; + while (((readCur) ~= (decodeLimit))) do + readBuf8[(6 + 65536 + 6) + tempBufSize] = readBuf8[readCur]; + tempBufSize=tempBufSize+1; + readCur=readCur+1; + end + + + + if (((readCur) ~= (decodeLimit))) then + return 17; + end + return 17; + + end + if ((checkEndMarkNow ~= 0) and ((dummyRes) ~= (2))) then + return 16; + end + bufLimit = readCur ; + else + bufLimit = decodeLimit - 20 ; + end + bufCur = readCur; + if (((LzmaDec_DecodeReal2(dicBufSize, bufLimit)) ~= (0))) then + --print("F") + return 1; + end + readCur = bufCur; + else + local ddRem = tempBufSize; + local lookAhead = 0; + while (((ddRem) < (20)) and ((lookAhead) < (decodeLimit - readCur))) do + readBuf8[(6 + 65536 + 6) + ddRem] = readBuf8[readCur + lookAhead]; + ddRem=ddRem+1; + lookAhead=lookAhead+1; + end + tempBufSize = ddRem; + if (((ddRem) < (20)) or (checkEndMarkNow ~= 0)) then + dummyRes = LzmaDec_TryDummy((6 + 65536 + 6), (6 + 65536 + 6) + ddRem) ; + if (((dummyRes) == (0))) then + readCur = readCur + lookAhead; + + + + if (((readCur) ~= (decodeLimit))) then + return 17; + end + return 17; + + end + if ((checkEndMarkNow ~= 0) and ((dummyRes) ~= (2))) then + return 16; + end + end + + bufCur = (6 + 65536 + 6); + if (((LzmaDec_DecodeReal2(0, (6 + 65536 + 6))) ~= (0))) then + --print("G") + return 1; + end + lookAhead = lookAhead - ddRem - (bufCur - (6 + 65536 + 6)) ; + readCur = readCur + lookAhead; + tempBufSize = 0; + end + end + if (((code) ~= 0)) then + --print("H"); + return 1; + end + return 15; +end +local function Preread(prSize) + + + + local prPos = readEnd - readCur; + local prGot; + + assert(((prSize) <= ((6 + 65536 + 6)))); + if (((prPos) < (prSize))) then + if ((((6 + 65536 + 6) - readCur) < (prSize))) then + + + readEnd = 0 + while readEnd < prPos do + readBuf8[readEnd] = readBuf8[readCur + readEnd]; + readEnd=readEnd+1 + end + readCur = 0; + end + while (((prPos) < (prSize))) do + + + + + prGot = READ_FROM_STDIN_TO_ARY8(readBuf8, readEnd, prSize - prPos); + if (((prGot + 1) <= (1))) then + break; + end + readEnd = readEnd + prGot; + prPos = prPos + prGot ; + end + end + + return prPos; + + + + + +end + +local function IgnoreVarint() + while (((readBuf8[readCur]) >= (0x80))) do readCur = readCur + 1 end + readCur = readCur + 1 +end + +local function IgnoreZeroBytes(izCount) + + while ((izCount) ~= (0)) do + readCur=readCur+1 + if (((readBuf8[readCur-1]) ~= (0))) then + return 57; + end + izCount=izCount-1; + end + return 0; +end + +local function GetLE4(glPos) + --return ((readBuf8[glPos] -bor- (readBuf8[glPos + 1] -blshift- 8)) -bor- (readBuf8[glPos + 2] -blshift- 16)) -bor- (readBuf8[glPos + 3] -blshift- 24); + --print("glPos", glPos) + return bitlib.band(readBuf8[glPos], 0xff) + bitlib.blshift(bitlib.band(readBuf8[glPos+1], 0xff), 8) + bitlib.blshift(bitlib.band(readBuf8[glPos+2], 0xff), 16) + bit.blshift(bitlib.band(readBuf8[glPos+3], 0xff), 24) +end + + +local function InitDecode() + + + dicBufSize = 0; + needInitDic = 1; + needInitState = 1; + needInitProp = 1; + dicPos = 0; + LzmaDec_InitDicAndState(1, 1); +end + +local function InitProp(ipByte) + + if (((ipByte) >= (9 * 5 * 5))) then + return 68; + end + lc = ipByte % 9; + lcm8 = 8 - lc; + ipByte = math.floor(ipByte / 9) ; + pb = math.floor(ipByte / 5); + lp = ipByte % 5; + if (((lc + lp) > (4))) then + return 68; + end + needInitProp = 0; + return 0; +end + + +local function WriteFrom(wfDicPos) + + + local lastTime = os.epoch("utc") + + + while (((wfDicPos) ~= (dicPos))) do + local wfGot = WRITE_TO_STDOUT_FROM_ARY8(dic8, wfDicPos, dicPos - wfDicPos); + if (wfGot -band- 0x80000000) ~= 0 then + return 9; + end + wfDicPos = wfDicPos + wfGot ; + if textutils and os.epoch("utc") - lastTime > 3000 then + --write(",") + lastTime = os.epoch("utc") + os.queueEvent(os.pullEvent()) + end + end + + return 0; +end + + + + + + +local function DecompressXzOrLzma() + local checksumSize; + local bhf; + local dxRes; + + + + + if (((Preread(12 + 12 + 6)) < (12 + 12 + 6))) then + return 6; + end + + if (((readBuf8[0]) == (0xfd)) and ((readBuf8[1]) == (0x37)) and + ((readBuf8[2]) == (0x7a)) and ((readBuf8[3]) == (0x58)) and + ((readBuf8[4]) == (0x5a)) and ((readBuf8[5]) == (0)) and + ((readBuf8[6]) == (0))) then --print("xz") + elseif ( + ( + (readBuf8[readCur]) <= (225) + ) and ( + (readBuf8[readCur + 13]) == (0) + ) and ( + ( + ( + (function() bhf = GetLE4(readCur + 9); return bhf end)() + ) == 0 + ) or ( + (bnot-bhf) == 0 + ) + ) and ( + ( + (function() dicSize = GetLE4(readCur + 1); return dicSize end)() + ) >= ((4096)) + ) and ( + (dicSize) < bitlib.band((1610612736 + 1), 0x7fffffff) + ) + ) then + + local readBufUS; + local srcLen; + local fromDicPos; + InitDecode(); + + + + + + if ((((function() dxRes = InitProp(readBuf8[readCur]); return dxRes end)()) ~= (0))) then + return dxRes; + end + if (((bhf) == 0)) then + readBufUS = GetLE4(readCur + 5); + dicBufSize = readBufUS; + if (not ((readBufUS) < bitlib.band((1610612736 + 1), 0x7fffffff))) then + return 2; + end + else + readBufUS = bhf ; + + dicBufSize = 1610612736; + end + + readCur = readCur + 13; + + + + + + + + while ((((function() srcLen = Preread((6 + 65536 + 6)); return srcLen end)()) ~= (0))) do + fromDicPos = dicPos ; + dxRes = LzmaDec_DecodeToDic(srcLen) ; + + if (((readBufUS) < (dicPos))) then + dicPos = readBufUS; + end + if ((((function() dxRes = WriteFrom(fromDicPos); return dxRes end)()) ~= (0))) then + return dxRes; + end + if (((dxRes) == (15))) then + break; + end + if (((dxRes) ~= (17)) and ((dxRes) ~= (0))) then + return dxRes; + end + if (((dicPos - readBufUS) == 0)) then + break; + end + end + return 0; + else + return 51; + end + + checksumSize = readBuf8[readCur + 7]; + if (((checksumSize) == (0))) then + checksumSize = 1; + elseif (((checksumSize) == (1))) then + checksumSize = 4; + elseif (((checksumSize) == (4))) then + checksumSize = 8; + elseif (((checksumSize) == (10))) then + checksumSize = 32; + else return 60; + end + + readCur = readCur + 12; + while true do + + local blockSizePad = 3; + local bhs; + local bhs2; + local dicSizeProp; + local readAtBlock; + assert(((readEnd - readCur) >= (12))); + readAtBlock = readCur ; + readCur=readCur+1; + if ((((function() bhs = readBuf8[readCur-1]; return bhs end)()) == (0))) then + break; + end + + bhs = (bhs + 1) -blshift- 2; + + + if (((Preread(bhs)) < (bhs))) then + return 6; + end + readAtBlock = readCur ; + bhf = readBuf8[readCur] ; + --print("bhf", string.format("%x\n", bhf)) + readCur=readCur+1; + if (((bhf -band- 2) ~= (0))) then + return 53; + end + + if (((bhf -band- 20) ~= (0))) then + return 54; + end + if (((bhf -band- 64) ~= (0))) then + + IgnoreVarint(); + end + if (((bhf -band- 128) ~= (0))) then + + IgnoreVarint(); + end + if (((readBuf8[readCur]) ~= (0x21))) then + return 55; + end + readCur=readCur+1; + if (((readBuf8[readCur]) ~= (1))) then + return 56; + end + readCur=readCur+1; + dicSizeProp = readBuf8[readCur] ; + readCur=readCur+1; + if (((dicSizeProp) > (40))) then + return 61; + end + + + + if (((dicSizeProp) > (37))) then + return 62; + end + dicSize = (((2) -bor- ((dicSizeProp) -band- 1)) -blshift- (math.floor((dicSizeProp) / 2) + 11)); + assert(((dicSize) >= ((4096)))); + + + + + + bhs2 = readCur - readAtBlock + 5 ; + + if (((bhs2) > (bhs))) then + return 58; + end + if ((((function() dxRes = IgnoreZeroBytes(bhs - bhs2); return dxRes end)()) ~= (0))) then + return dxRes; + end + readCur = readCur + 4; + + + do + + local chunkUS; + local chunkCS; + local initDic; + InitDecode(); + + while true do + local control; + assert(((dicPos) == (dicBufSize))); + + + + if (((Preread(6)) < (6))) then + return 6; + end + control = readBuf8[readCur] ; + + if (((control) == (0))) then + + readCur=readCur+1; + break; + elseif ((((bitlib.band((control - 3), 0xff))) < (0x80 - 3))) then + return 59; + end + chunkUS = (readBuf8[readCur + 1] -blshift- 8) + readBuf8[readCur + 2] + 1 ; + --print("chunkUS", chunkUS, "readCur", readCur, "@1", readBuf8[readCur + 1], "@2", readBuf8[readCur + 2]) + if (((control) < (3))) then + initDic = (((control) == (1)) and 1 or 0); + chunkCS = chunkUS ; + readCur = readCur + 3; + + blockSizePad = blockSizePad - 3; + if ((initDic ~= 0)) then + needInitState = 1; + needInitProp = needInitState; + needInitDic = 0; + elseif ((needInitDic ~= 0)) then + --print("I") + return 1; + end + LzmaDec_InitDicAndState(initDic, 0); + else + local mode = ((bitlib.rshift(((control)), (5))) -band- 3); + local initState = (((mode) ~= (0)) and 1 or 0); + local isProp = ((((control -band- 64)) ~= (0)) and 1 or 0); + initDic = (((mode) == (3)) and 1 or 0); + chunkUS = chunkUS + ((control -band- 31) -blshift- 16) ; + chunkCS = (readBuf8[readCur + 3] -blshift- 8) + readBuf8[readCur + 4] + 1 ; + if ((isProp ~= 0)) then + if ((((function() dxRes = InitProp(readBuf8[readCur + 5]); return dxRes end)()) ~= (0))) then + return dxRes; + end + readCur=readCur+1; + blockSizePad=blockSizePad-1; + else + if ((needInitProp ~= 0)) then + return 67; + end + end + readCur = readCur + 5; + blockSizePad = blockSizePad - 5 ; + if (((initDic == 0) and (needInitDic ~= 0)) or ((initState == 0) and (needInitState ~= 0))) then + --print("J") + return 1; + end + LzmaDec_InitDicAndState(initDic, initState); + needInitDic = 0; + needInitState = 0; + end + assert(((dicPos) == (dicBufSize))); + dicBufSize = dicBufSize + chunkUS; + + if (((dicBufSize) > (1610612736))) then + return 2; + end + + + + + if (((Preread(chunkCS + 6)) < (chunkCS))) then + return 6; + end + + if (((control) < (0x80))) then + + while (((dicPos) ~= (dicBufSize))) do + dic8[dicPos] = readBuf8[readCur] -band- 0xFF; + dicPos=dicPos+1; + readCur=readCur+1; + end + if (((checkDicSize) == (0)) and ((dicSize - processedPos) <= (chunkUS))) then + checkDicSize = dicSize; + end + processedPos = processedPos + chunkUS; + else + + + if ((((function() dxRes = LzmaDec_DecodeToDic(chunkCS); return dxRes end)()) ~= (0))) then + return dxRes; + end + end + if (((dicPos) ~= (dicBufSize))) then + return 65; + end + if ((((function() dxRes = WriteFrom(dicPos - chunkUS); return dxRes end)()) ~= (0))) then + return dxRes; + end + blockSizePad = blockSizePad - chunkCS ; + + + + + end + end + + + + + if (((Preread(7 + 12 + 6)) < (7 + 12 + 6))) then + return 6; + end + + + if ((((function() dxRes = IgnoreZeroBytes(blockSizePad -band- 3); return dxRes end)()) ~= (0))) then + return dxRes; + end + readCur = readCur + checksumSize; + end + + return 0; +end + +local error_table = { + UNKNOWN_ERROR = -1, + OK = 0, + ERROR_DATA = 1, + ERROR_MEM = 2, + ERROR_CRC = 3, + ERROR_UNSUPPORTED = 4, + ERROR_PARAM = 5, + ERROR_INPUT_EOF = 6, + ERROR_OUTPUT_EOF = 7, + ERROR_READ = 8, + ERROR_WRITE = 9, + ERROR_FINISHED_WITH_MARK = 15, + ERROR_NOT_FINISHED = 16, + ERROR_NEEDS_MORE_INPUT = 17, + ERROR_CHUNK_NOT_CONSUMED = 18, + ERROR_NEEDS_MORE_INPUT_PARTIAL = 17, + ERROR_BAD_MAGIC = 51, + ERROR_BAD_STREAM_FLAGS = 52, + ERROR_UNSUPPORTED_FILTER_COUNT = 53, + ERROR_BAD_BLOCK_FLAGS = 54, + ERROR_UNSUPPORTED_FILTER_ID = 55, + ERROR_UNSUPPORTED_FILTER_PROPERTIES_SIZE = 56, + ERROR_BAD_PADDING = 57, + ERROR_BLOCK_HEADER_TOO_LONG = 58, + ERROR_BAD_CHUNK_CONTROL_BYTE = 59, + ERROR_BAD_CHECKSUM_TYPE = 60, + ERROR_BAD_DICTIONARY_SIZE = 61, + ERROR_UNSUPPORTED_DICTIONARY_SIZE = 62, + ERROR_FEED_CHUNK = 63, + ERROR_NOT_FINISHED_WITH_MARK = 64, + ERROR_BAD_DICPOS = 65, + ERROR_MISSING_INITPROP = 67, + ERROR_BAD_LCLPPB_PROP = 68, +} + +return { + --- Decompresses an XZ or LZMA file using file I/O. Both files will be closed after decompression finishes. + -- @param input The input file (path) to read from + -- @param output The output file (path) to write to + -- @return Whether the decompression succeeded + -- @return If failure, an error code describing the issue + DecompressXzOrLzmaFile = function(input, output) + if type(input) ~= "number" and type(input) ~= "string" and type(input)~="table" then error("bad argument #1 (expected string or file, got " .. type(input) .. ")", 2) end + if type(output) ~= "number" and type(output) ~= "string" and type(input)~="table" then error("bad argument #2 (expected string or file, got " .. type(output) .. ")", 2) end + str_input = nil + str_output = nil + if type(input) == "string" then + input = syscall.open(input, "r") + if input == nil then return false, -1 end + end + if type(output) == "string" then + output = syscall.open(output, "w") + if output == nil then return false, -1 end + end + ResetGlobals() + stdin=input + stdout=output + local ok, res = pcall(DecompressXzOrLzma) + syscall.close(input) + syscall.close(output) + if not ok then + if res then error(res .. "\n") end + return false, -1 + else return res == 0, res end + end, + + --- Decompresses XZ or LZMA data. + -- @param input The input data to decompress + -- @return The decompressed data, or nil if failure + -- @return If failure, an error code describing the issue + DecompressXzOrLzmaString = function(input) + if type(input) ~= "string" then error("bad argument #1 (expected string, got " .. type(input) .. ")", 2) end + str_input = input + str_output = "" + ResetGlobals() + local ok, res = pcall(DecompressXzOrLzma) + if not ok then + if res then error(res .. "\n") end + return -1 + elseif res == 0 then return str_output + elseif res == 53 and #str_output > 0 then return str_output, res + else return nil, res end + end, + + --- Translates error codes to a semi-understandable meaning. + -- @param code The error code + -- @return A string describing the error + GetError = function(code) for k,v in pairs(error_table) do if v == code then return k end end return nil end, + --- Error code table for your convenience + Errors = error_table, +} \ No newline at end of file diff --git a/Src/Hyperion-firmware-cct/lib/modules/cc-tweaked/22_http.kmod b/packages/Hyperion-core.pkg similarity index 100% rename from Src/Hyperion-firmware-cct/lib/modules/cc-tweaked/22_http.kmod rename to packages/Hyperion-core.pkg diff --git a/prod/Hyperion-core/lib/http b/packages/Hyperion-firmware-cct.pkg similarity index 100% rename from prod/Hyperion-core/lib/http rename to packages/Hyperion-firmware-cct.pkg diff --git a/prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/22_http.kmod b/packages/Hyperion-kernel.pkg similarity index 100% rename from prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/22_http.kmod rename to packages/Hyperion-kernel.pkg diff --git a/prod/Hyperion-kernel/etc/shadow b/packages/HyperionOS.pkg similarity index 100% rename from prod/Hyperion-kernel/etc/shadow rename to packages/HyperionOS.pkg diff --git a/packages/spm.pkg b/packages/spm.pkg new file mode 100644 index 0000000..4fa49b8 --- /dev/null +++ b/packages/spm.pkg @@ -0,0 +1,14 @@ +{ + "authors":[ + "Astronand" + ], + "versions":{ + "1.0.0":{ + "dependencies":[ + "json", + "xz" + ], + "package":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/spm.sp" + } + } +} \ No newline at end of file diff --git a/prod/Hyperion-core/lib/colors b/prod/Hyperion-core/lib/colors deleted file mode 100644 index c8a00cd..0000000 --- a/prod/Hyperion-core/lib/colors +++ /dev/null @@ -1 +0,0 @@ -return{white=0xFFFFFF,red=0xFF0000,green=0x00FF00,blue=0x0000FF,cyan=0x00FFFF,yellow=0xFFFF00,purple=0xFF00FF,black=0x000000,gray=0x888888,lightgrey=0xBBBBBB,darkgrey=0x444444,orange=0xFF8800,mint=0x00FF88,brown=0xa52a2a,chocolate=0xd2691e} diff --git a/prod/Hyperion-core/lib/fs b/prod/Hyperion-core/lib/fs deleted file mode 100644 index 5268349..0000000 --- a/prod/Hyperion-core/lib/fs +++ /dev/null @@ -1 +0,0 @@ -local a={}function a.open(b,c)local d=syscall.open(b,c)local e={close=function()return syscall.close(d)end,flush=function()syscall.fsync(d)end}if c=="r"then e.read=function(f)local g=syscall.read(d,f)return g end;e.readAll=function(h)local i={}while true do local j=syscall.read(d,h or 65536)if j==nil or#j==0 then break end;table.insert(i,j)end;return table.concat(i)end;e.readLine=function(h)local k={}local l=""local m=h or 65536;local n=false;while true do local o=l:find("\n")if o then local p=l:sub(1,o-1)l=l:sub(o+1)return p end;if n then if l~=""then local q=l;l=""return q else return nil end end;local j=syscall.read(d,m)if not j or j==""then n=true else l=l..j end end end elseif c=="w"then e.write=function(g)return syscall.write(d,g)end elseif c=="a"then e.write=function(g)return syscall.write(d,g)end else error("Invalid mode '"..c.."'",2)end;return e end;function a.readAllText(b)local r=a.open(b,"r")if not r then return false end;local s=r.readAll()r.close()return s end;function a.writeAllText(b,g)local r=a.open(b,"w")r.write(g)r.close()end;function a.appendAllText(b,g)local r=a.open(b,"a")if not r then return false end;r.write(g)r.close()end;function a.mkdir(b)return syscall.mkdir(b)end;function a.remove(b)return syscall.remove(b)end;function a.list(b)return syscall.listdir(b)end;function a.type(b)return syscall.type(b)end;function a.stat(b)return syscall.stat(b)end;function a.exists(b)return syscall.exists(b)end;function a.getcwd()return syscall.getcwd()end;function a.chdir(b)return syscall.chdir(b)end;function a.isDir(b)return syscall.type(b)=="directory"end;return a diff --git a/prod/Hyperion-core/lib/io b/prod/Hyperion-core/lib/io deleted file mode 100644 index e0eb470..0000000 --- a/prod/Hyperion-core/lib/io +++ /dev/null @@ -1,6 +0,0 @@ -local io = {} -local fs = require("fs") - -function io.open(path, mode) - return fs.open(path, mode) -end \ No newline at end of file diff --git a/prod/Hyperion-firmware-ac/boot/ac/boot.lua b/prod/Hyperion-firmware-ac/boot/ac/boot.lua deleted file mode 100644 index 9b7a5fa..0000000 --- a/prod/Hyperion-firmware-ac/boot/ac/boot.lua +++ /dev/null @@ -1 +0,0 @@ -local a={...}local b=a[1]local c=components:getFirst("gpu")local d=nil;local e,f=0,0;local g,h=128,25;if c then d=c:newBuffer(g,h)for i,j in components:list()do if i=="screen"then c:assignBuffer(d,j)end end end;local function k(l)e,f=d:pasteText(e,f,"SCROLL_SPILL_CLEAR",l)f=f+1;e=0;if f>=h then f=h-1;d:newline()end end;local function m(n)c:freeAllBuffers()d=c:newBuffer(g,h)for i,j in components:list()do if i=="screen"then c:assignBuffer(d,j)end end;term.setBackgroundColor(0x1)term.setTextColor(0x4)term.clear()term.setCursorPos(1,1)term.write("A critical error occurred while loading the system:")term.setCursorPos(1,3)k(n)while true do end end;local o,n=xpcall(function()local p={}local q={coroutine=true,debug=true,_VERSION=true,assert=true,collectgarbage=true,error=true,gcinfo=true,getmetatable=true,ipairs=true,__inext=true,load=true,math=true,next=true,pairs=true,pcall=true,rawequal=true,rawget=true,rawlen=true,rawset=true,select=true,setmetatable=true,string=true,table=true,tonumber=true,tostring=true,type=true,xpcall=true,_G=true}local debug=debug;for r,j in pairs(_G)do if not q[r]or q[r]==nil then p[r]=j;_G[r]=nil end end;local function s(t)local u=t:read()local v={u or""}local w=1;local x=false;local function y()return table.concat(v)end;local function z(A)v={A}end;local function B()t.write(y())end;local t={}function t:read(C)assert(not x,"file is closed")local A=y()local D=#A;if not C then local E=A:sub(w)w=D+1;return E end;local E=A:sub(w,w+C-1)w=w+#E;return E end;function t:write(F)assert(not x,"file is closed")local A=y()local G=A:sub(1,w-1)local H=A:sub(w+#F)z(G..F..H)w=w+#F;return true end;function t:seek(I,J)assert(not x,"file is closed")local A=y()local D=#A;I=I or"cur"J=J or 0;if I=="set"then w=J+1 elseif I=="cur"then w=w+J elseif I=="end"then w=D+J+1 else error("invalid whence")end;if w<1 then w=1 end;if w>D+1 then w=D+1 end;return w-1 end;function t:close()assert(not x,"file is closed")B()x=true end;function t:flush()assert(not x,"file is closed")B()end;return t end;local function K(L)local t=b:open(L,"r")if not t then m("Could not open file: "..L)end;local y=t:read()return y end;local M=load(K("/boot/kernel.lua"),"@Kernel")local N=load(K("/boot/ac/initdisks"),"@Init_disks")(p)local O=load(K("/boot/initfs"),"@InitFs")()if not M then m("Could not load kernel.")end;if not N then m("Could not load initdisks.")end;if not O then m("Could not load initfs.")end;local P=p.components:getFirst("computer")local Q=p.components:getFirst("uefi")local R={time=function()return p.os.epoch("utc")end,clock=function()return p.os.clock()*1000 end,shutdown=p.os.shutdown,reboot=p.os.reboot,getMachineEvent=function()return P:getMachineEvent()end,getEEPROM=function()return Q.data end,setEEPROM=function(S,l)Q.data=l end}local T={[0x1]=1,[0x2]=2,[0x4]=3,[0x8]=4,[0x10]=5,[0x20]=6,[0x40]=7,[0x80]=8,[0x100]=9,[0x200]=10,[0x400]=11,[0x800]=12,[0x1000]=13,[0x2000]=14,[0x4000]=15,[0x8000]=16}local U={0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000}p.term.setBackgroundColor(0x8000)p.term.setTextColor(0x1000)p.term.clear()p.term.setCursorPos(1,1)local V=coroutine.create(function()local o,n=xpcall(M,debug.traceback,p,N,"cct","/sbin/init",{print=function(S,l)k(l.."\n")end,printInline=function(S,l)k(l)end,clear=function()p.term.clear()p.term.setCursorPos(1,1)end,setCursorPos=function(S,W,X)p.term.setCursorPos(W,X)end,getCursorPos=function()return p.term.getCursorPos()end,getSize=function()return p.term.getSize()end,setBackgroundColor=function(S,Y)p.term.setBackgroundColor(U[Y])end,setTextColor=function(S,Y)p.term.setTextColor(U[Y])end,getBackgroundColor=function()return T[p.term.getBackgroundColor()]end,getTextColor=function()return T[p.term.getTextColor()]end},R,O,"$")if not o then m(n)end end)function coroutine.resumeWithTimeout(Z,_,...)local a0=R.time()debug.sethook(Z,function()if R.time()>a0+_ then return coroutine.yield("timeout")end end,"",1000)local a1={coroutine.resume(Z,...)}if a1[1]and a1[2]=="timeout"then return"timeout"elseif a1[1]==false then return"error",a1[2]else debug.sethook(Z)return"success",table.unpack(a1,2)end end;k("Loaded in "..tostring(p.os.clock()).." seconds.\n")while true do local a2,n=coroutine.resumeWithTimeout(V,50)p.os.queueEvent("NoSleep")local a3=false;while not a3 do local a4={coroutine.yield()}if a4[1]=="key"then queueEvent("keyPressed",1,a4[2])if acekeys[a4[2]]then queueEvent("keyTyped",1,acekeys[a4[2]])end elseif a4[1]=="char"then queueEvent("keyTyped",1,a4[2])elseif a4[1]=="key_up"then queueEvent("keyReleased",1,a4[2])elseif a4[1]=="disk"then queueEvent("componentAdded","disk")elseif a4[1]=="disk_eject"then queueEvent("componentRemoved","disk")elseif a4[1]=="modem_message"then queueEvent("modem_message",table.unpack(a4,2))elseif a4[1]=="rednet_message"then queueEvent("rednet_message",table.unpack(a4,2))elseif a4[1]=="http_success"then queueEvent("http_success",table.unpack(a4,2))elseif a4[1]=="http_failure"then queueEvent("http_failure",table.unpack(a4,2))elseif a4[1]=="NoSleep"then a3=true end end;if a2=="error"or coroutine.status(V)=="dead"then m("Kernel error: "..tostring(n))coroutine.yield("key")end end end,debug.traceback)if not o then m("Fatal error during boot: "..n)end;while true do coroutine.yield()end diff --git a/prod/Hyperion-firmware-ccpc/boot/ccpc/boot.lua b/prod/Hyperion-firmware-ccpc/boot/ccpc/boot.lua deleted file mode 100644 index 6c67bfb..0000000 --- a/prod/Hyperion-firmware-ccpc/boot/ccpc/boot.lua +++ /dev/null @@ -1 +0,0 @@ -local a=({...})[1]or"/$"local term=term;local os=os;local function b(c)local d,e=term.getCursorPos()local f,g=term.getSize()for h=1,#c do local i=c:sub(h,h)if i=="\n"then e=e+1;d=1 elseif i=="\t"then local j=4;local k=j-(d-1)%j;term.write(string.rep(" ",k))d=d+k elseif i=="\b"then if d>1 then d=d-1;term.setCursorPos(d,e)term.write(" ")term.setCursorPos(d,e)end else if d<=f and e<=g then term.setCursorPos(d,e)term.write(i)d=d+1 end end;if d>f then d=1;e=e+1 end;if e-1>=g then term.scroll(1)e=g;term.setCursorPos(d,e)end end;term.setCursorPos(d,e)end;local function l(m)term.setBackgroundColor(0x1)term.setTextColor(0x4)term.clear()term.setCursorPos(1,1)term.write("A critical error occurred while loading the system:")term.setCursorPos(1,3)b(m)while true do end end;term.setCursorBlink(false)local n,m=xpcall(function()local o={BOOT_DRIVE_PATH=a}local p={coroutine=true,debug=true,_VERSION=true,assert=true,collectgarbage=true,error=true,gcinfo=true,getmetatable=true,ipairs=true,__inext=true,load=true,math=true,next=true,pairs=true,pcall=true,rawequal=true,rawget=true,rawlen=true,rawset=true,select=true,setmetatable=true,string=true,table=true,tonumber=true,tostring=true,type=true,xpcall=true,_G=true}local debug=debug;for h,q in pairs(_G)do if not p[h]or p[h]==nil then o[h]=q;_G[h]=nil end end;local r={[o.keys.enter]="\n",[o.keys.tab]="\t",[o.keys.backspace]="\b",[o.keys.up]="\17",[o.keys.down]="\18",[o.keys.left]="\19",[o.keys.right]="\20"}function sleep(s)local t=o.os.clock()+s;while t>o.os.clock()do end end;o.term.setPaletteColor(0x1,0xFFFFFF)o.term.setPaletteColor(0x2,0xFF0000)o.term.setPaletteColor(0x4,0x00FF00)o.term.setPaletteColor(0x8,0x0000FF)o.term.setPaletteColor(0x10,0x00FFFF)o.term.setPaletteColor(0x20,0xFF00FF)o.term.setPaletteColor(0x40,0xFFFF00)o.term.setPaletteColor(0x80,0xFF6D00)o.term.setPaletteColor(0x100,0x6DFF55)o.term.setPaletteColor(0x200,0x24FFFF)o.term.setPaletteColor(0x400,0x924900)o.term.setPaletteColor(0x800,0x6D6D55)o.term.setPaletteColor(0x1000,0xDBDBAA)o.term.setPaletteColor(0x2000,0x6D00FF)o.term.setPaletteColor(0x4000,0xB6FF00)o.term.setPaletteColor(0x8000,0x000000)local function u(v)local w=o.fs.open(v,"r")if not w then l("Could not open file: "..v)end;local x=w.readAll()w.close()return x end;local y=load(u(a.."/boot/kernel.lua"),"@Kernel")local z=load(u(a.."/boot/cct/initdisks"),"@Init_disks")(o)local A=load(u(a.."/boot/initfs"),"@InitFs")()if not y then l("Could not load kernel.")end;if not z then l("Could not load initdisks.")end;if not A then l("Could not load initfs.")end;if not o.fs.exists("/nvram.dat")then local w=o.fs.open("/nvram.dat","w")w.write("Hello, World!")w.close()end;local B;if o.fs.exists("/startup.lua")then B="/startup.lua"elseif o.fs.exists("/eeprom")then B="/eeprom"end;local C={}local function D(E,...)table.insert(C,{E,...})end;local F={[0x000000]=0x0001,[0xFFFFFF]=0x0002,[0xFF0000]=0x0004,[0x00FF00]=0x0008,[0x0000FF]=0x0010,[0x00FFFF]=0x0020,[0xFF00FF]=0x0040,[0xFFFF00]=0x0080,[0xFF6D00]=0x0100,[0x6DFF55]=0x0200,[0x24FFFF]=0x0400,[0x924900]=0x0800,[0x6D6D55]=0x1000,[0xDBDBAA]=0x2000,[0x6D00FF]=0x4000,[0xB6FF00]=0x8000}local G,H=0x6D6D55,0x000000;local I,J,K,L={},{},{},0;local function M(N,O)local P=nil;local Q=math.huge;for R,S in pairs(N)do local T=math.abs(R-O)if T=16 then K[V]=J[V]J[V]=nil;I[V]=nil;return K[V]end;return J[V]end;local W=M(F,V)if not W then return nil end;local X=F[W]J[V]=X;I[V]=1;return X end;local Y={getEpochMs=function()return o.os.epoch("utc")end,getUptime=function()return o.os.clock()*1000 end,date=function()return o.os.date("!%Y-%m-%dT%H:%M:%SZ",o.os.epoch("utc")/1000)end,getMachineEvent=function()if#C>0 then return table.unpack(table.remove(C,1))else return nil end end,getEEPROM=function()return u(B)end,setEEPROM=function(S,c)local g=o.fs.open(B,"w")g.write(c)g.close()end,initfs=A,disks=z,screenCtl={print=function(S,c)b(c.."\n")end,printInline=function(S,c)b(c)end,clear=function()o.term.clear()o.term.setCursorPos(1,1)end,setCursorPos=function(S,d,e)o.term.setCursorPos(d,e)end,getCursorPos=function()return o.term.getCursorPos()end,getSize=function()return o.term.getSize()end,setBackgroundColor=function(S,Z)o.term.setBackgroundColor(U(Z))end,setTextColor=function(S,Z)o.term.setTextColor(U(Z))end,getBackgroundColor=function()return H end,getTextColor=function()return G end,enable=function()end,disable=function()end},architecture="cct",getNvram=function()return u("/nvram.dat")end,setNvram=function(S,c)local g=o.fs.open("/nvram.dat","w")g.write(c)g.close()end,firmware=o,reboot=false}o.term.setBackgroundColor(0x8000)o.term.setTextColor(0x1000)o.term.clear()o.term.setCursorPos(1,1)local _=coroutine.create(function()local n,m=xpcall(y,debug.traceback,Y)if not n and not Y.reboot then l(m)end;if m then o.os.reboot()else o.os.shutdown()end end)function coroutine.resumeWithTimeout(a0,a1,...)local a2=Y.getEpochMs()debug.sethook(a0,function()if Y.getEpochMs()>a2+a1 then return coroutine.yield("timeout")end end,"",1000)local a3={coroutine.resume(a0,...)}if a3[1]and a3[2]=="timeout"then return"timeout"elseif a3[1]==false then return"error",a3[2]else debug.sethook(a0)return"success",table.unpack(a3,2)end end;b("Loaded in "..tostring(o.os.clock()).." seconds.\n")while true do local a4,m=coroutine.resumeWithTimeout(_,50)o.os.queueEvent("NoSleep")local a5=false;while not a5 do local E={coroutine.yield()}if E[1]=="key"then D("keyPressed",1,E[2])if r[E[2]]then D("keyTyped",1,r[E[2]])end elseif E[1]=="char"then D("keyTyped",1,E[2])elseif E[1]=="key_up"then D("keyReleased",1,E[2])elseif E[1]=="disk"then D("componentAdded","disk")elseif E[1]=="disk_eject"then D("componentRemoved","disk")elseif E[1]=="modem_message"then D("modem_message",table.unpack(E,2))elseif E[1]=="rednet_message"then D("rednet_message",table.unpack(E,2))elseif E[1]=="http_success"then D("http_success",table.unpack(E,2))elseif E[1]=="http_failure"then D("http_failure",table.unpack(E,2))elseif E[1]=="NoSleep"then a5=true end end;if a4=="error"or coroutine.status(_)=="dead"then if Y.reboot then o.os.reboot()end;l("Kernel error: "..tostring(m))coroutine.yield("key")end;z:refresh()end end,debug.traceback)if not n then l("Fatal error during boot: "..m)end;while true do coroutine.yield("key")end diff --git a/prod/Hyperion-firmware-ccpc/boot/ccpc/eeprom b/prod/Hyperion-firmware-ccpc/boot/ccpc/eeprom deleted file mode 100644 index 9bba429..0000000 --- a/prod/Hyperion-firmware-ccpc/boot/ccpc/eeprom +++ /dev/null @@ -1 +0,0 @@ -local a=({...})[1]or"/$"local b={...}local c={keys=true,bit32=true,bit=true,ccemux=true,config=true,coroutine=true,debug=true,fs=true,http=true,mounter=true,os=true,periphemu=true,peripheral=true,redstone=true,rs=true,term=true,utf8=true,_HOST=true,_CC_DEFAULT_SETTINGS=true,_CC_DISABLE_LUA51_FEATURES=true,_VERSION=true,assert=true,collectgarbage=true,error=true,gcinfo=true,getfenv=true,getmetatable=true,ipairs=true,__inext=true,load=true,loadstring=true,math=true,newproxy=true,next=true,pairs=true,pcall=true,rawequal=true,rawget=true,rawlen=true,rawset=true,select=true,setfenv=true,setmetatable=true,string=true,table=true,tonumber=true,tostring=true,type=true,unpack=true,xpcall=true,turtle=true,pocket=true,commands=true,_G=true}local d={}for e in pairs(_G)do if not c[e]then table.insert(d,e)end end;for f,e in ipairs(d)do _G[e]=nil end;local g=_G.term.native()for f,h in ipairs{"nativePaletteColor","nativePaletteColour","screenshot"}do g[h]=_G.term[h]end;_G.term=g;if _G.http then _G.http.checkURL=_G.http.checkURLAsync;_G.http.websocket=_G.http.websocketAsync end;if _G.commands then _G.commands=_G.commands.native end;if _G.turtle then _G.turtle.native,_G.turtle.craft=nil end;local i={os={"version","pullEventRaw","pullEvent","run","loadAPI","unloadAPI","sleep"},http=_G.http and{"get","post","put","delete","patch","options","head","trace","listen","checkURLAsync","websocketAsync"},fs={"complete","isDriveRoot"}}for e,j in pairs(i)do for f,k in ipairs(j)do _G[e][k]=nil end end;local l=error;_G.error=function()end;_G.term.redirect=function()end;function _G.term.native()_G.term.native=nil;_G.term.redirect=nil;_G.error=l;term.setBackgroundColor(32768)term.setTextColor(1)term.setCursorPos(1,1)term.setCursorBlink(true)term.clear()local m=fs.open(a.."/boot/cct/boot.lua","r")if m==nil then term.setCursorBlink(false)term.setTextColor(16384)term.write("Could not find /boot/cct/boot.lua. UnBIOS cannot continue.")term.setCursorPos(1,2)term.write("Press any key to continue")coroutine.yield("key")os.shutdown()end;local n,o=loadstring(m.readAll(),"@bootloader")m.close()if n==nil then term.setCursorBlink(false)term.setTextColor(16384)term.write("Could not load /boot/cc/boot.lua. UnBIOS cannot continue.")term.setCursorPos(1,2)term.write(o)term.setCursorPos(1,3)term.write("Press any key to continue")coroutine.yield("key")os.shutdown()end;setfenv(n,_G)local p=os.shutdown;os.shutdown=function()os.shutdown=p;return n(a)end end;if debug then local function q(r,s,t,u)local v,w,x=1,debug.getupvalue(r[s],u)while w~=t and w~=nil do w,x=debug.getupvalue(r[s],v)v=v+1 end;r[s]=x or r[s]end;q(_G,"loadstring","nativeloadstring",1)q(_G,"load","nativeload",5)if http then q(http,"request","nativeHTTPRequest",3)end;q(os,"shutdown","nativeShutdown",1)q(os,"reboot","nativeReboot",1)if turtle then q(turtle,"equipLeft","v",1)q(turtle,"equipRight","v",1)end;do local v,w,x=1,debug.getupvalue(peripheral.isPresent,2)while w~="native"and w~=nil do w,x=debug.getupvalue(peripheral.isPresent,v)v=v+1 end;_G.peripheral=x or peripheral end end diff --git a/prod/Hyperion-firmware-ccpc/boot/ccpc/initdisks b/prod/Hyperion-firmware-ccpc/boot/ccpc/initdisks deleted file mode 100644 index dc41dfd..0000000 --- a/prod/Hyperion-firmware-ccpc/boot/ccpc/initdisks +++ /dev/null @@ -1 +0,0 @@ -local a=({...})[1]local b=a.BOOT_DRIVE_PATH;local c=a.fs;local d=a.peripheral;local e={}local f={"top","bottom","left","right","front","back"}function e.getNames()local g={}for h=1,#f do local i=f[h]if d.isPresent(i)then table.insert(g,i)if d.hasType(i,"peripheral_hub")then local j=d.call(i,"getNamesRemote")for k,l in ipairs(j)do table.insert(g,l)end end end end;return g end;function e.isPresent(l)if d.isPresent(l)then return true end;for h=1,#f do local i=f[h]if d.hasType(i,"peripheral_hub")and d.call(i,"isPresentRemote",l)then return true end end;return false end;function e.getType(e)if type(e)=="string"then if d.isPresent(e)then return d.getType(e)end;for h=1,#f do local i=f[h]if d.hasType(i,"peripheral_hub")and d.call(i,"isPresentRemote",e)then return d.call(i,"getTypeRemote",e)end end;return nil else local m=getmetatable(e)if not m or m.__name~="peripheral"or type(m.types)~="table"then error("bad argument #1 (table is not a peripheral)",2)end;return table.unpack(m.types)end end;function e.hasType(e,n)if type(e)=="string"then if d.isPresent(e)then return d.hasType(e,n)end;for h=1,#f do local i=f[h]if d.hasType(i,"peripheral_hub")and d.call(i,"isPresentRemote",e)then return d.call(i,"hasTypeRemote",e,n)end end;return nil else local m=getmetatable(e)if not m or m.__name~="peripheral"or type(m.types)~="table"then error("bad argument #1 (table is not a peripheral)",2)end;return m.types[n]~=nil end end;function e.getMethods(l)if d.isPresent(l)then return d.getMethods(l)end;for h=1,#f do local i=f[h]if d.hasType(i,"peripheral_hub")and d.call(i,"isPresentRemote",l)then return d.call(i,"getMethodsRemote",l)end end;return nil end;function e.getName(e)local m=getmetatable(e)if not m or m.__name~="peripheral"or type(m.name)~="string"then error("bad argument #1 (table is not a peripheral)",2)end;return m.name end;function e.call(l,o,...)if d.isPresent(l)then return d.call(l,o,...)end;for h=1,#f do local i=f[h]if d.hasType(i,"peripheral_hub")and d.call(i,"isPresentRemote",l)then return d.call(i,"callRemote",l,o,...)end end;return nil end;function e.wrap(l)local p=e.getMethods(l)if not p then return nil end;local q={e.getType(l)}for r=1,#q do q[q[r]]=true end;local s=setmetatable({},{__name="peripheral",name=l,type=q[1],types=q})for k,o in ipairs(p)do s[o]=function(...)return e.call(l,o,...)end end;return s end;function e.find(t,u)local g={}for k,l in ipairs(e.getNames())do if e.hasType(l,t)then local v=e.wrap(l)if u==nil or u(l,v)then table.insert(g,v)end end end;return table.unpack(g)end;local w={}local x={}local function y(z)if not z or z==""then return"/"end;return c.combine("/",z)end;local function A(B,C,D,E)C=y(C)local F={address=B,isReadOnly=function()return D end}function F:spaceUsed()return c.getCapacity(C)-c.getFreeSpace(C)end;function F:spaceTotal()return c.getCapacity(C)end;function F:list(z)local G=c.combine(C,z)if not c.exists(G)or not c.isDir(G)then return nil,"not directory"end;return c.list(G)end;function F:fileExists(z)local G=c.combine(C,z)return c.exists(G)and not c.isDir(G)end;function F:directoryExists(z)local G=c.combine(C,z)return c.exists(G)and c.isDir(G)end;function F:type(z)local G=c.combine(C,z)if not c.exists(G)then return nil elseif c.isDir(G)then return"directory"else return"file"end end;function F:makeDirectory(z)local G=c.combine(C,z)c.makeDir(G)return true end;function F:remove(z)local G=c.combine(C,z)if c.exists(G)then c.delete(G)end;return true end;function F:setLabel(H)E.setLabel(H)end;function F:getLabel(H)return E.getLabel()end;function F:attributes(z)local G=c.combine(C,z)return c.attributes(G)end;function F:open(z,I)local G=c.combine(C,z)return c.open(G,I)end;return F end;x["$"]=A("$",b,false,{setLabel=function(H)local J=c.open("/.label","w")J.write(H)J.close()end,getLabel=function()local J=c.open("/.label","r")if not J then return"$"end;local H=J.readAll()J.close()return H end})x["rom"]=A("rom","/rom",true,{setLabel=function(H)error("Device is read-only")end,getLabel=function()return"cctrom"end})local function K()w={}for k,F in ipairs({e.find("drive")})do if F.isDiskPresent()then w[tostring(F.getDiskID())]=A("cctdisk"..tostring(F.getDiskID()),F.getMountPath(),false,c)end end end;local function L()K()local M={}for B,N in pairs(x)do M[B]=N end;for B,N in pairs(w)do M[B]=N end;return pairs(M)end;return{refresh=K,list=L} diff --git a/prod/Hyperion-firmware-ccpc/lib/modules/ccpc/25_gfx.kmod b/prod/Hyperion-firmware-ccpc/lib/modules/ccpc/25_gfx.kmod deleted file mode 100644 index 4b3a2db..0000000 --- a/prod/Hyperion-firmware-ccpc/lib/modules/ccpc/25_gfx.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b=a.apis;local c=b.peripheral;local d={"top","bottom","left","right","front","back"}local e={}function e.getNames()local f={}for g=1,#d do local h=d[g]if c.isPresent(h)then table.insert(f,h)if c.hasType(h,"peripheral_hub")then local i=c.call(h,"getNamesRemote")for j,k in ipairs(i)do table.insert(f,k)end end end end;return f end;function e.isPresent(k)if c.isPresent(k)then return true end;for g=1,#d do local h=d[g]if c.hasType(h,"peripheral_hub")and c.call(h,"isPresentRemote",k)then return true end end;return false end;function e.getType(e)if type(e)=="string"then if c.isPresent(e)then return c.getType(e)end;for g=1,#d do local h=d[g]if c.hasType(h,"peripheral_hub")and c.call(h,"isPresentRemote",e)then return c.call(h,"getTypeRemote",e)end end;return nil else local l=getmetatable(e)if not l or l.__name~="peripheral"or type(l.types)~="table"then error("bad argument #1 (table is not a peripheral)",2)end;return table.unpack(l.types)end end;function e.hasType(e,m)if type(e)=="string"then if c.isPresent(e)then return c.hasType(e,m)end;for g=1,#d do local h=d[g]if c.hasType(h,"peripheral_hub")and c.call(h,"isPresentRemote",e)then return c.call(h,"hasTypeRemote",e,m)end end;return nil else local l=getmetatable(e)if not l or l.__name~="peripheral"or type(l.types)~="table"then error("bad argument #1 (table is not a peripheral)",2)end;return l.types[m]~=nil end end;function e.getMethods(k)if c.isPresent(k)then return c.getMethods(k)end;for g=1,#d do local h=d[g]if c.hasType(h,"peripheral_hub")and c.call(h,"isPresentRemote",k)then return c.call(h,"getMethodsRemote",k)end end;return nil end;function e.getName(e)local l=getmetatable(e)if not l or l.__name~="peripheral"or type(l.name)~="string"then error("bad argument #1 (table is not a peripheral)",2)end;return l.name end;function e.call(k,n,...)if c.isPresent(k)then return c.call(k,n,...)end;for g=1,#d do local h=d[g]if c.hasType(h,"peripheral_hub")and c.call(h,"isPresentRemote",k)then return c.call(h,"callRemote",k,n,...)end end;return nil end;function e.wrap(k)local o=e.getMethods(k)if not o then return nil end;local p={e.getType(k)}for q=1,#p do p[p[q]]=true end;local r=setmetatable({},{__name="peripheral",name=k,type=p[1],types=p})for j,n in ipairs(o)do r[n]=function(...)return e.call(k,n,...)end end;return r end;function e.find(s,t)local f={}for j,k in ipairs(e.getNames())do if e.hasType(k,s)then local u=e.wrap(k)if t==nil or t(k,u)then table.insert(f,u)end end end;return table.unpack(f)end;local v={[0x1]=1,[0x2]=2,[0x4]=3,[0x8]=4,[0x10]=5,[0x20]=6,[0x40]=7,[0x80]=8,[0x100]=9,[0x200]=10,[0x400]=11,[0x800]=12,[0x1000]=13,[0x2000]=14,[0x4000]=15,[0x8000]=16}local w={0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000}local function x(y,z)local A,B=z.getCursorPos()local C,D=z.getSize()for q=1,#y do local E=y:sub(q,q)if E=="\n"then B=B+1;A=1 elseif E=="\t"then local F=4;local G=F-(A-1)%F;z.write(string.rep(" ",G))A=A+G elseif E=="\b"then if A>1 then A=A-1;z.setCursorPos(A,B)z.write(" ")z.setCursorPos(A,B)end else if A<=C and B<=D then z.setCursorPos(A,B)z.write(E)A=A+1 end end;if A>C then A=1;B=B+1 end;if B-1>=D then z.scroll(1)B=D;z.setCursorPos(A,B)end end;z.setCursorPos(A,B)end;a.devfs.data.tty={}local H,I=false,false;local function J(K)if K then return"T"else return"F"end end;local function L(M,N,O)a.devfs.data["tty"][N]=function(P,Q)if P=="type"then return"character device"elseif P=="open"then local D={read=function(R)local S=""for q=1,R or 1 do local T={O()}if T[1]then S=S..T[1]end end;if S==""then S=nil end;return S end,write=function(U)x(U,M)end,size=function()local V={M.getSize()}return table.concat(V,";")end,clear=function()M.clear()M.setCursorPos(1,1)end,gpos=function()local V={M.getCursorPos()}return table.concat(V,";")end,spos=function(A,B)return M.setCursorPos(A,B)end,sfgc=function(E)return M.setTextColor(w[E])end,sbgc=function(E)return M.setBackgroundColor(w[E])end,gfgc=function()return v[M.getTextColor()]end,gbgc=function()return v[M.getBackgroundColor()]end,gctrl=function()return J(H)..";"..J(I)end}if Q=="rw"then return D elseif Q=="r"then D["write"]=nil;return D elseif Q=="w"then D["read"]=nil;return D end end end end;local W=a.newFifo()a.processes.cctmond=function()local X=false;while true do local T={a.EFI:getMachineEvent()}if T[1]then local Y=T[1]local Z=T[3]local _={[b.keys.a]=1,[b.keys.b]=2,[b.keys.c]=3,[b.keys.d]=4,[b.keys.e]=5,[b.keys.f]=6,[b.keys.g]=7,[b.keys.h]=8,[b.keys.i]=9,[b.keys.j]=10,[b.keys.k]=11,[b.keys.l]=12,[b.keys.m]=13,[b.keys.n]=14,[b.keys.o]=15,[b.keys.p]=16,[b.keys.q]=17,[b.keys.r]=18,[b.keys.s]=19,[b.keys.t]=20,[b.keys.u]=21,[b.keys.v]=22,[b.keys.w]=23,[b.keys.x]=24,[b.keys.y]=25,[b.keys.z]=26}if Y=="keyPressed"then if Z==b.keys.leftCtrl or Z==b.keys.rightCtrl then H=true elseif Z==b.keys.leftAlt or Z==b.keys.rightAlt then I=true end;if H then local a0=_[Z]if a0 then if a0==3 then for j,a1 in ipairs(syscall.getTasks())do syscall.sigsend(a1,1)end else W.push(string.char(a0))end end else local a2={[b.keys.up]="",[b.keys.down]="",[b.keys.right]="",[b.keys.left]="",[b.keys.home]="",[b.keys["end"]]="",[b.keys.pageUp]="[5~",[b.keys.pageDown]="[6~",[b.keys.delete]="[3~"}local a3=a2[Z]if a3 then W.push(a3)end end elseif Y=="keyReleased"then if Z==b.keys.leftCtrl or Z==b.keys.rightCtrl then H=false elseif Z==b.keys.leftAlt or Z==b.keys.rightAlt then I=false end elseif Y=="keyTyped"then if Z then W.push(Z)end end;X=false else X=true end;if X then sleep(0.05)end end end;L(b.term,"1",W.pop)for q,a4 in ipairs({e.find("monitor")})do a4.setTextScale(.5)a4.write("Initializing...")L(a4,tostring(q+1),function()end)end diff --git a/prod/Hyperion-firmware-cct/boot/cct/boot.lua b/prod/Hyperion-firmware-cct/boot/cct/boot.lua deleted file mode 100644 index 556fd65..0000000 --- a/prod/Hyperion-firmware-cct/boot/cct/boot.lua +++ /dev/null @@ -1 +0,0 @@ -local a=({...})[1]or"/$"local term=term;local os=os;local function b(c)local d,e=term.getCursorPos()local f,g=term.getSize()for h=1,#c do local i=c:sub(h,h)if i=="\n"then e=e+1;d=1 elseif i=="\t"then local j=4;local k=j-(d-1)%j;term.write(string.rep(" ",k))d=d+k elseif i=="\b"then if d>1 then d=d-1;term.setCursorPos(d,e)term.write(" ")term.setCursorPos(d,e)end else if d<=f and e<=g then term.setCursorPos(d,e)term.write(i)d=d+1 end end;if d>f then d=1;e=e+1 end;if e-1>=g then term.scroll(1)e=g;term.setCursorPos(d,e)end end;term.setCursorPos(d,e)end;local function l(m)term.setBackgroundColor(0x1)term.setTextColor(0x4)term.clear()term.setCursorPos(1,1)term.write("A critical error occurred while loading the system:")term.setCursorPos(1,3)b(m)while true do end end;term.setCursorBlink(false)local n,m=xpcall(function()local o={BOOT_DRIVE_PATH=a}local p={coroutine=true,debug=true,_VERSION=true,assert=true,collectgarbage=true,error=true,gcinfo=true,getmetatable=true,ipairs=true,__inext=true,load=true,math=true,next=true,pairs=true,pcall=true,rawequal=true,rawget=true,rawlen=true,rawset=true,select=true,setmetatable=true,string=true,table=true,tonumber=true,tostring=true,type=true,xpcall=true,_G=true}local debug=debug;for h,q in pairs(_G)do if not p[h]or p[h]==nil then o[h]=q;_G[h]=nil end end;local r={[o.keys.enter]="\n",[o.keys.tab]="\t",[o.keys.backspace]="\b",[o.keys.up]="\17",[o.keys.down]="\18",[o.keys.left]="\19",[o.keys.right]="\20"}function sleep(s)local t=o.os.clock()+s;while t>o.os.clock()do end end;o.term.setPaletteColor(0x1,0xFFFFFF)o.term.setPaletteColor(0x2,0xFF0000)o.term.setPaletteColor(0x4,0x00FF00)o.term.setPaletteColor(0x8,0x0000FF)o.term.setPaletteColor(0x10,0x00FFFF)o.term.setPaletteColor(0x20,0xFF00FF)o.term.setPaletteColor(0x40,0xFFFF00)o.term.setPaletteColor(0x80,0xFF6D00)o.term.setPaletteColor(0x100,0x6DFF55)o.term.setPaletteColor(0x200,0x24FFFF)o.term.setPaletteColor(0x400,0x924900)o.term.setPaletteColor(0x800,0x6D6D55)o.term.setPaletteColor(0x1000,0xDBDBAA)o.term.setPaletteColor(0x2000,0x6D00FF)o.term.setPaletteColor(0x4000,0xB6FF00)o.term.setPaletteColor(0x8000,0x000000)local function u(v)local w=o.fs.open(v,"r")if not w then l("Could not open file: "..v)end;local x=w.readAll()w.close()return x end;local y=load(u(a.."/boot/kernel.lua"),"@Kernel")local z=load(u(a.."/boot/cct/initdisks"),"@Init_disks")(o)local A=load(u(a.."/boot/initfs"),"@InitFs")()if not y then l("Could not load kernel.")end;if not z then l("Could not load initdisks.")end;if not A then l("Could not load initfs.")end;if not o.fs.exists("/nvram.dat")then local w=o.fs.open("/nvram.dat","w")w.write("Hello, World!")w.close()end;local B;if o.fs.exists("/startup.lua")then B="/startup.lua"elseif o.fs.exists("/eeprom")then B="/eeprom"end;local C={}local function D(E,...)table.insert(C,{E,...})end;local F={[0x000000]=0x0001,[0xFFFFFF]=0x0002,[0xFF0000]=0x0004,[0x00FF00]=0x0008,[0x0000FF]=0x0010,[0x00FFFF]=0x0020,[0xFF00FF]=0x0040,[0xFFFF00]=0x0080,[0xFF6D00]=0x0100,[0x6DFF55]=0x0200,[0x24FFFF]=0x0400,[0x924900]=0x0800,[0x6D6D55]=0x1000,[0xDBDBAA]=0x2000,[0x6D00FF]=0x4000,[0xB6FF00]=0x8000}local G,H=0x6D6D55,0x000000;local I,J,K,L={},{},{},0;local function M(N,O)local P=nil;local Q=math.huge;for R,S in pairs(N)do if R==O then return R end;local T=math.abs(R-O)if T=16 then K[V]=J[V]J[V]=nil;I[V]=nil;return K[V]end;return J[V]end;local W=M(F,V)if not W then return nil end;local X=F[W]J[V]=X;I[V]=1;return X end;local Y={}local Z=o.peripheral;local _={"top","bottom","left","right","front","back"}function Y.getNames()local a0={}for a1=1,#_ do local a2=_[a1]if Z.isPresent(a2)then table.insert(a0,a2)if Z.hasType(a2,"peripheral_hub")then local a3=Z.call(a2,"getNamesRemote")for S,a4 in ipairs(a3)do table.insert(a0,a4)end end end end;return a0 end;function Y.isPresent(a4)if Z.isPresent(a4)then return true end;for a1=1,#_ do local a2=_[a1]if Z.hasType(a2,"peripheral_hub")and Z.call(a2,"isPresentRemote",a4)then return true end end;return false end;function Y.getType(Y)if type(Y)=="string"then if Z.isPresent(Y)then return Z.getType(Y)end;for a1=1,#_ do local a2=_[a1]if Z.hasType(a2,"peripheral_hub")and Z.call(a2,"isPresentRemote",Y)then return Z.call(a2,"getTypeRemote",Y)end end;return nil else local a5=getmetatable(Y)if not a5 or a5.__name~="peripheral"or type(a5.types)~="table"then error("bad argument #1 (table is not a peripheral)",2)end;return table.unpack(a5.types)end end;function Y.hasType(Y,a6)if type(Y)=="string"then if Z.isPresent(Y)then return Z.hasType(Y,a6)end;for a1=1,#_ do local a2=_[a1]if Z.hasType(a2,"peripheral_hub")and Z.call(a2,"isPresentRemote",Y)then return Z.call(a2,"hasTypeRemote",Y,a6)end end;return nil else local a5=getmetatable(Y)if not a5 or a5.__name~="peripheral"or type(a5.types)~="table"then error("bad argument #1 (table is not a peripheral)",2)end;return a5.types[a6]~=nil end end;function Y.getMethods(a4)if Z.isPresent(a4)then return Z.getMethods(a4)end;for a1=1,#_ do local a2=_[a1]if Z.hasType(a2,"peripheral_hub")and Z.call(a2,"isPresentRemote",a4)then return Z.call(a2,"getMethodsRemote",a4)end end;return nil end;function Y.getName(Y)local a5=getmetatable(Y)if not a5 or a5.__name~="peripheral"or type(a5.name)~="string"then error("bad argument #1 (table is not a peripheral)",2)end;return a5.name end;function Y.call(a4,a7,...)if Z.isPresent(a4)then return Z.call(a4,a7,...)end;for a1=1,#_ do local a2=_[a1]if Z.hasType(a2,"peripheral_hub")and Z.call(a2,"isPresentRemote",a4)then return Z.call(a2,"callRemote",a4,a7,...)end end;return nil end;function Y.wrap(a4)local a8=Y.getMethods(a4)if not a8 then return nil end;local a9={Y.getType(a4)}for h=1,#a9 do a9[a9[h]]=true end;local aa=setmetatable({},{__name="peripheral",name=a4,type=a9[1],types=a9})for S,a7 in ipairs(a8)do aa[a7]=function(...)return Y.call(a4,a7,...)end end;return aa end;function Y.find(ab,ac)local a0={}for S,a4 in ipairs(Y.getNames())do if Y.hasType(a4,ab)then local ad=Y.wrap(a4)if ac==nil or ac(a4,ad)then table.insert(a0,ad)end end end;return table.unpack(a0)end;local ae={Y.find("monitor")}for h=1,#ae do ae[h].setTextScale(.5)ae[h].clear()ae[h].setCursorPos(1,1)ae[h].write("Initializing...")end;local af={getEpochMs=function()return o.os.epoch("utc")end,getUptime=function()return o.os.clock()*1000 end,date=function()return o.os.date("!%Y-%m-%dT%H:%M:%SZ",o.os.epoch("utc")/1000)end,getMachineEvent=function()if#C>0 then return table.unpack(table.remove(C,1))else return nil end end,getEEPROM=function()return u(B)end,setEEPROM=function(S,c)local g=o.fs.open(B,"w")g.write(c)g.close()end,initfs=A,disks=z,screenCtl={print=function(S,c)b(c.."\n")end,printInline=function(S,c)b(c)end,clear=function()o.term.clear()o.term.setCursorPos(1,1)end,setCursorPos=function(S,d,e)o.term.setCursorPos(d,e)end,getCursorPos=function()return o.term.getCursorPos()end,getSize=function()return o.term.getSize()end,setBackgroundColor=function(S,ag)o.term.setBackgroundColor(U(ag))end,setTextColor=function(S,ag)o.term.setTextColor(U(ag))end,getBackgroundColor=function()return H end,getTextColor=function()return G end,enable=function()end,disable=function()end},architecture="cct",getNvram=function()return u("/nvram.dat")end,setNvram=function(S,c)local g=o.fs.open("/nvram.dat","w")g.write(c)g.close()end,firmware=o,reboot=false,beep=function()end}o.term.setBackgroundColor(0x8000)o.term.setTextColor(0x1000)o.term.clear()o.term.setCursorPos(1,1)local ah=coroutine.create(function()local n,m=xpcall(y,debug.traceback,af)if not n and not af.reboot then l(m)end;if m then o.os.reboot()else o.os.shutdown()end end)function coroutine.resumeWithTimeout(ai,aj,...)local ak=af.getEpochMs()debug.sethook(ai,function()if af.getEpochMs()>ak+aj then return coroutine.yield("timeout")end end,"",1000)local al={coroutine.resume(ai,...)}if al[1]and al[2]=="timeout"then return"timeout"elseif al[1]==false then return"error",al[2]else debug.sethook(ai)return"success",table.unpack(al,2)end end;af.screenCtl:print("Loaded in "..tostring(o.os.clock()).." seconds.\n")while true do local am,m=coroutine.resumeWithTimeout(ah,50)o.os.queueEvent("NoSleep")local an=false;while not an do local E={coroutine.yield()}if E[1]=="key"then D("keyPressed",1,E[2])if r[E[2]]then D("keyTyped",1,r[E[2]])end elseif E[1]=="char"then D("keyTyped",1,E[2])elseif E[1]=="key_up"then D("keyReleased",1,E[2])elseif E[1]=="disk"then D("componentAdded","disk")elseif E[1]=="disk_eject"then D("componentRemoved","disk")elseif E[1]=="modem_message"then D("modem_message",table.unpack(E,2))elseif E[1]=="rednet_message"then D("rednet_message",table.unpack(E,2))elseif E[1]=="http_success"then D("http_success",table.unpack(E,2))elseif E[1]=="http_failure"then D("http_failure",table.unpack(E,2))elseif E[1]=="NoSleep"then an=true end end;if am=="error"or coroutine.status(ah)=="dead"then if af.reboot then o.os.reboot()end;l("Kernel error: "..tostring(m))coroutine.yield("key")end;z:refresh()end end,debug.traceback)if not n then l("Fatal error during boot: "..m)end;while true do coroutine.yield("key")end diff --git a/prod/Hyperion-firmware-cct/boot/cct/eeprom b/prod/Hyperion-firmware-cct/boot/cct/eeprom deleted file mode 100644 index 9bba429..0000000 --- a/prod/Hyperion-firmware-cct/boot/cct/eeprom +++ /dev/null @@ -1 +0,0 @@ -local a=({...})[1]or"/$"local b={...}local c={keys=true,bit32=true,bit=true,ccemux=true,config=true,coroutine=true,debug=true,fs=true,http=true,mounter=true,os=true,periphemu=true,peripheral=true,redstone=true,rs=true,term=true,utf8=true,_HOST=true,_CC_DEFAULT_SETTINGS=true,_CC_DISABLE_LUA51_FEATURES=true,_VERSION=true,assert=true,collectgarbage=true,error=true,gcinfo=true,getfenv=true,getmetatable=true,ipairs=true,__inext=true,load=true,loadstring=true,math=true,newproxy=true,next=true,pairs=true,pcall=true,rawequal=true,rawget=true,rawlen=true,rawset=true,select=true,setfenv=true,setmetatable=true,string=true,table=true,tonumber=true,tostring=true,type=true,unpack=true,xpcall=true,turtle=true,pocket=true,commands=true,_G=true}local d={}for e in pairs(_G)do if not c[e]then table.insert(d,e)end end;for f,e in ipairs(d)do _G[e]=nil end;local g=_G.term.native()for f,h in ipairs{"nativePaletteColor","nativePaletteColour","screenshot"}do g[h]=_G.term[h]end;_G.term=g;if _G.http then _G.http.checkURL=_G.http.checkURLAsync;_G.http.websocket=_G.http.websocketAsync end;if _G.commands then _G.commands=_G.commands.native end;if _G.turtle then _G.turtle.native,_G.turtle.craft=nil end;local i={os={"version","pullEventRaw","pullEvent","run","loadAPI","unloadAPI","sleep"},http=_G.http and{"get","post","put","delete","patch","options","head","trace","listen","checkURLAsync","websocketAsync"},fs={"complete","isDriveRoot"}}for e,j in pairs(i)do for f,k in ipairs(j)do _G[e][k]=nil end end;local l=error;_G.error=function()end;_G.term.redirect=function()end;function _G.term.native()_G.term.native=nil;_G.term.redirect=nil;_G.error=l;term.setBackgroundColor(32768)term.setTextColor(1)term.setCursorPos(1,1)term.setCursorBlink(true)term.clear()local m=fs.open(a.."/boot/cct/boot.lua","r")if m==nil then term.setCursorBlink(false)term.setTextColor(16384)term.write("Could not find /boot/cct/boot.lua. UnBIOS cannot continue.")term.setCursorPos(1,2)term.write("Press any key to continue")coroutine.yield("key")os.shutdown()end;local n,o=loadstring(m.readAll(),"@bootloader")m.close()if n==nil then term.setCursorBlink(false)term.setTextColor(16384)term.write("Could not load /boot/cc/boot.lua. UnBIOS cannot continue.")term.setCursorPos(1,2)term.write(o)term.setCursorPos(1,3)term.write("Press any key to continue")coroutine.yield("key")os.shutdown()end;setfenv(n,_G)local p=os.shutdown;os.shutdown=function()os.shutdown=p;return n(a)end end;if debug then local function q(r,s,t,u)local v,w,x=1,debug.getupvalue(r[s],u)while w~=t and w~=nil do w,x=debug.getupvalue(r[s],v)v=v+1 end;r[s]=x or r[s]end;q(_G,"loadstring","nativeloadstring",1)q(_G,"load","nativeload",5)if http then q(http,"request","nativeHTTPRequest",3)end;q(os,"shutdown","nativeShutdown",1)q(os,"reboot","nativeReboot",1)if turtle then q(turtle,"equipLeft","v",1)q(turtle,"equipRight","v",1)end;do local v,w,x=1,debug.getupvalue(peripheral.isPresent,2)while w~="native"and w~=nil do w,x=debug.getupvalue(peripheral.isPresent,v)v=v+1 end;_G.peripheral=x or peripheral end end diff --git a/prod/Hyperion-firmware-cct/boot/cct/initdisks b/prod/Hyperion-firmware-cct/boot/cct/initdisks deleted file mode 100644 index dc41dfd..0000000 --- a/prod/Hyperion-firmware-cct/boot/cct/initdisks +++ /dev/null @@ -1 +0,0 @@ -local a=({...})[1]local b=a.BOOT_DRIVE_PATH;local c=a.fs;local d=a.peripheral;local e={}local f={"top","bottom","left","right","front","back"}function e.getNames()local g={}for h=1,#f do local i=f[h]if d.isPresent(i)then table.insert(g,i)if d.hasType(i,"peripheral_hub")then local j=d.call(i,"getNamesRemote")for k,l in ipairs(j)do table.insert(g,l)end end end end;return g end;function e.isPresent(l)if d.isPresent(l)then return true end;for h=1,#f do local i=f[h]if d.hasType(i,"peripheral_hub")and d.call(i,"isPresentRemote",l)then return true end end;return false end;function e.getType(e)if type(e)=="string"then if d.isPresent(e)then return d.getType(e)end;for h=1,#f do local i=f[h]if d.hasType(i,"peripheral_hub")and d.call(i,"isPresentRemote",e)then return d.call(i,"getTypeRemote",e)end end;return nil else local m=getmetatable(e)if not m or m.__name~="peripheral"or type(m.types)~="table"then error("bad argument #1 (table is not a peripheral)",2)end;return table.unpack(m.types)end end;function e.hasType(e,n)if type(e)=="string"then if d.isPresent(e)then return d.hasType(e,n)end;for h=1,#f do local i=f[h]if d.hasType(i,"peripheral_hub")and d.call(i,"isPresentRemote",e)then return d.call(i,"hasTypeRemote",e,n)end end;return nil else local m=getmetatable(e)if not m or m.__name~="peripheral"or type(m.types)~="table"then error("bad argument #1 (table is not a peripheral)",2)end;return m.types[n]~=nil end end;function e.getMethods(l)if d.isPresent(l)then return d.getMethods(l)end;for h=1,#f do local i=f[h]if d.hasType(i,"peripheral_hub")and d.call(i,"isPresentRemote",l)then return d.call(i,"getMethodsRemote",l)end end;return nil end;function e.getName(e)local m=getmetatable(e)if not m or m.__name~="peripheral"or type(m.name)~="string"then error("bad argument #1 (table is not a peripheral)",2)end;return m.name end;function e.call(l,o,...)if d.isPresent(l)then return d.call(l,o,...)end;for h=1,#f do local i=f[h]if d.hasType(i,"peripheral_hub")and d.call(i,"isPresentRemote",l)then return d.call(i,"callRemote",l,o,...)end end;return nil end;function e.wrap(l)local p=e.getMethods(l)if not p then return nil end;local q={e.getType(l)}for r=1,#q do q[q[r]]=true end;local s=setmetatable({},{__name="peripheral",name=l,type=q[1],types=q})for k,o in ipairs(p)do s[o]=function(...)return e.call(l,o,...)end end;return s end;function e.find(t,u)local g={}for k,l in ipairs(e.getNames())do if e.hasType(l,t)then local v=e.wrap(l)if u==nil or u(l,v)then table.insert(g,v)end end end;return table.unpack(g)end;local w={}local x={}local function y(z)if not z or z==""then return"/"end;return c.combine("/",z)end;local function A(B,C,D,E)C=y(C)local F={address=B,isReadOnly=function()return D end}function F:spaceUsed()return c.getCapacity(C)-c.getFreeSpace(C)end;function F:spaceTotal()return c.getCapacity(C)end;function F:list(z)local G=c.combine(C,z)if not c.exists(G)or not c.isDir(G)then return nil,"not directory"end;return c.list(G)end;function F:fileExists(z)local G=c.combine(C,z)return c.exists(G)and not c.isDir(G)end;function F:directoryExists(z)local G=c.combine(C,z)return c.exists(G)and c.isDir(G)end;function F:type(z)local G=c.combine(C,z)if not c.exists(G)then return nil elseif c.isDir(G)then return"directory"else return"file"end end;function F:makeDirectory(z)local G=c.combine(C,z)c.makeDir(G)return true end;function F:remove(z)local G=c.combine(C,z)if c.exists(G)then c.delete(G)end;return true end;function F:setLabel(H)E.setLabel(H)end;function F:getLabel(H)return E.getLabel()end;function F:attributes(z)local G=c.combine(C,z)return c.attributes(G)end;function F:open(z,I)local G=c.combine(C,z)return c.open(G,I)end;return F end;x["$"]=A("$",b,false,{setLabel=function(H)local J=c.open("/.label","w")J.write(H)J.close()end,getLabel=function()local J=c.open("/.label","r")if not J then return"$"end;local H=J.readAll()J.close()return H end})x["rom"]=A("rom","/rom",true,{setLabel=function(H)error("Device is read-only")end,getLabel=function()return"cctrom"end})local function K()w={}for k,F in ipairs({e.find("drive")})do if F.isDiskPresent()then w[tostring(F.getDiskID())]=A("cctdisk"..tostring(F.getDiskID()),F.getMountPath(),false,c)end end end;local function L()K()local M={}for B,N in pairs(x)do M[B]=N end;for B,N in pairs(w)do M[B]=N end;return pairs(M)end;return{refresh=K,list=L} diff --git a/prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/01_periph.kmod b/prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/01_periph.kmod deleted file mode 100644 index e85aa09..0000000 --- a/prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/01_periph.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...a.cct={}a.cct.peripheral={}local b=a.cct.peripheral;local c=a.apis;local d=c.peripheral;local e={"top","bottom","left","right","front","back"}function b.getNames()local f={}for g=1,#e do local h=e[g]if d.isPresent(h)then table.insert(f,h)if d.hasType(h,"peripheral_hub")then local i=d.call(h,"getNamesRemote")for j,k in ipairs(i)do table.insert(f,k)end end end end;return f end;function b.isPresent(k)if d.isPresent(k)then return true end;for g=1,#e do local h=e[g]if d.hasType(h,"peripheral_hub")and d.call(h,"isPresentRemote",k)then return true end end;return false end;function b.getType(b)if type(b)=="string"then if d.isPresent(b)then return d.getType(b)end;for g=1,#e do local h=e[g]if d.hasType(h,"peripheral_hub")and d.call(h,"isPresentRemote",b)then return d.call(h,"getTypeRemote",b)end end;return nil else local l=getmetatable(b)if not l or l.__name~="peripheral"or type(l.types)~="table"then error("bad argument #1 (table is not a peripheral)",2)end;return table.unpack(l.types)end end;function b.hasType(b,m)if type(b)=="string"then if d.isPresent(b)then return d.hasType(b,m)end;for g=1,#e do local h=e[g]if d.hasType(h,"peripheral_hub")and d.call(h,"isPresentRemote",b)then return d.call(h,"hasTypeRemote",b,m)end end;return nil else local l=getmetatable(b)if not l or l.__name~="peripheral"or type(l.types)~="table"then error("bad argument #1 (table is not a peripheral)",2)end;return l.types[m]~=nil end end;function b.getMethods(k)if d.isPresent(k)then return d.getMethods(k)end;for g=1,#e do local h=e[g]if d.hasType(h,"peripheral_hub")and d.call(h,"isPresentRemote",k)then return d.call(h,"getMethodsRemote",k)end end;return nil end;function b.getName(b)local l=getmetatable(b)if not l or l.__name~="peripheral"or type(l.name)~="string"then error("bad argument #1 (table is not a peripheral)",2)end;return l.name end;function b.call(k,n,...)if d.isPresent(k)then return d.call(k,n,...)end;for g=1,#e do local h=e[g]if d.hasType(h,"peripheral_hub")and d.call(h,"isPresentRemote",k)then return d.call(h,"callRemote",k,n,...)end end;return nil end;function b.wrap(k)local o=b.getMethods(k)if not o then return nil end;local p={b.getType(k)}for q=1,#p do p[p[q]]=true end;local r=setmetatable({},{__name="peripheral",name=k,type=p[1],types=p})for j,n in ipairs(o)do r[n]=function(...)return b.call(k,n,...)end end;return r end;function b.find(s,t)local f={}for j,k in ipairs(b.getNames())do if b.hasType(k,s)then local u=b.wrap(k)if t==nil or t(k,u)then table.insert(f,u)end end end;return table.unpack(f)end diff --git a/prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/25_tty.kmod b/prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/25_tty.kmod deleted file mode 100644 index e2af0fd..0000000 --- a/prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/25_tty.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b=a.cct.peripheral;local c={[0xFFFFFF]=0x0001,[0xFF0000]=0x0002,[0x00FF00]=0x0004,[0x0000FF]=0x0008,[0x00FFFF]=0x0010,[0xFF00FF]=0x0020,[0xFFFF00]=0x0040,[0xFF6D00]=0x0080,[0x6DFF55]=0x0100,[0x24FFFF]=0x0200,[0x924900]=0x0400,[0x6D6D55]=0x0800,[0xDBDBAA]=0x1000,[0x6D00FF]=0x2000,[0xB6FF00]=0x4000,[0x000000]=0x8000}local d={0xFFFFFF,0xFF0000,0x00FF00,0x0000FF,0x00FFFF,0xFF00FF,0xFFFF00,0xFF6D00,0x6DFF55,0x24FFFF,0x924900,0x6D6D55,0xDBDBAA,0x6D00FF,0xB6FF00,0x000000}local e,f=0x6D6D55,0x000000;local g,h,i,j={},{},{},0;local function k(l,m)local n=nil;local o=math.huge;for p,q in pairs(l)do if p==m then return p end;local r=math.abs(p-m)if r=16 then i[t]=h[t]h[t]=nil;g[t]=nil;return i[t]end;return h[t]end;local u=k(c,t)if not u then return nil end;local v=c[u]h[t]=v;g[t]=1;return v end;local function w(x,y)local z,A=y.getCursorPos()local B,C=y.getSize()for D=1,#x do local E=x:sub(D,D)if E=="\n"then A=A+1;z=1 elseif E=="\t"then local F=4;local G=F-(z-1)%F;y.write(string.rep(" ",G))z=z+G elseif E=="\b"then if z>1 then z=z-1;y.setCursorPos(z,A)y.write(" ")y.setCursorPos(z,A)end else if z<=B and A<=C then y.setCursorPos(z,A)y.write(E)z=z+1 end end;if z>B then z=1;A=A+1 end;if A-1>=C then y.scroll(1)A=C;y.setCursorPos(z,A)end end;y.setCursorPos(z,A)end;a.devfs.data.tty={}a.cct.ctrl,a.cct.alt=false,false;local function H(I)if I then return"T"else return"F"end end;local function J(K,L,M)K.setPaletteColor(0x1,0xFFFFFF)K.setPaletteColor(0x2,0xFF0000)K.setPaletteColor(0x4,0x00FF00)K.setPaletteColor(0x8,0x0000FF)K.setPaletteColor(0x10,0x00FFFF)K.setPaletteColor(0x20,0xFF00FF)K.setPaletteColor(0x40,0xFFFF00)K.setPaletteColor(0x80,0xFF6D00)K.setPaletteColor(0x100,0x6DFF55)K.setPaletteColor(0x200,0x24FFFF)K.setPaletteColor(0x400,0x924900)K.setPaletteColor(0x800,0x6D6D55)K.setPaletteColor(0x1000,0xDBDBAA)K.setPaletteColor(0x2000,0x6D00FF)K.setPaletteColor(0x4000,0xB6FF00)K.setPaletteColor(0x8000,0x000000)a.devfs.data["tty"][L]=function(N,O)if N=="type"then return"Terminal"elseif N=="open"then local C={read=function(P)local Q=""for D=1,P or 1 do local R={M()}if R[1]then Q=Q..R[1]end end;if Q==""then Q=nil end;return Q end,write=function(S)w(S,K)end,size=function()local T={K.getSize()}return table.concat(T,";")end,clear=function()K.clear()K.setCursorPos(1,1)end,gpos=function()local T={K.getCursorPos()}return table.concat(T,";")end,spos=function(z,A)return K.setCursorPos(z,A)end,sfgc=function(E)e=E;return K.setTextColor(s(E))end,sbgc=function(E)f=E;return K.setBackgroundColor(s(E))end,gfgc=function()return e end,gbgc=function()return f end,gctrl=function()return H(a.cct.ctrl)..";"..H(a.cct.alt)end,gplt=function()return d end}if O=="rw"then return C elseif O=="r"then C["write"]=nil;return C elseif O=="w"then C["read"]=nil;return C end end end end;local U=a.newFifo()a.cct.fifo=U;J(a.apis.term,"1",U.pop)for D,V in ipairs({b.find("monitor")})do V.setTextScale(.5)V.write("Initializing...")J(V,tostring(D+1),function()end)end diff --git a/prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/30_deamon.kmod b/prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/30_deamon.kmod deleted file mode 100644 index 4d25109..0000000 --- a/prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/30_deamon.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b=a.apis.keys;a.processes.cctdeamon=function()local c=false;while true do local d={a.EFI:getMachineEvent()}if d[1]then local e=d[1]local f=d[3]local g={[b.a]=1,[b.b]=2,[b.c]=3,[b.d]=4,[b.e]=5,[b.f]=6,[b.g]=7,[b.h]=8,[b.i]=9,[b.j]=10,[b.k]=11,[b.l]=12,[b.m]=13,[b.n]=14,[b.o]=15,[b.p]=16,[b.q]=17,[b.r]=18,[b.s]=19,[b.t]=20,[b.u]=21,[b.v]=22,[b.w]=23,[b.x]=24,[b.y]=25,[b.z]=26}if e=="keyPressed"then if f==b.leftCtrl or f==b.rightCtrl then a.cct.ctrl=true elseif f==b.leftAlt or f==b.rightAlt then a.cct.alt=true end;if a.cct.ctrl then local h=g[f]if h then if h==3 then for i,j in ipairs(syscall.getTasks())do syscall.sigsend(j,1)end else a.cct.fifo.push(string.char(h))end end else local k={[b.up]="",[b.down]="",[b.right]="",[b.left]="",[b.home]="",[b["end"]]="",[b.pageUp]="[5~",[b.pageDown]="[6~",[b.delete]="[3~"}local l=k[f]if l then a.cct.fifo.push(l)end end elseif e=="keyReleased"then if f==b.leftCtrl or f==b.rightCtrl then a.cct.ctrl=false elseif f==b.leftAlt or f==b.rightAlt then a.cct.alt=false end elseif e=="keyTyped"then if f then a.cct.fifo.push(f)end elseif e=="http_success"then a.cct.httpqueue[d[2]]=nil;a.cct.httpresponse[d[2]]=d[3]elseif e=="http_failure"then a.cct.httpqueue[d[2]]=nil;a.cct.httperror[d[2]]=d[3]end;c=false else c=true end;if c then sleep(0.05)end end end diff --git a/prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/51_gpio.kmod b/prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/51_gpio.kmod deleted file mode 100644 index 0c5efa9..0000000 --- a/prod/Hyperion-firmware-cct/lib/modules/cc-tweaked/51_gpio.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b=a.apis.rs;local c={top=1,bottom=2,left=3,right=4,front=5,back=6}local function d(e)return function(f,g)if f=="w"then if type(g)~="boolean"then error("data: expected bool")end;b.setOutput(e,g)elseif f=="wa"then if type(g)~="number"then error("data: expected bool")end;b.setAnalogOutput(e,g)elseif f=="r"then return b.getInput(e)elseif f=="ra"then return b.getAnalogInput(e)end end end;for e,h in pairs(c)do local i=d(e)a.gpio[e]=i;a.gpio[h]=i end diff --git a/prod/Hyperion-firmware-oc/boot/oc/boot.lua b/prod/Hyperion-firmware-oc/boot/oc/boot.lua deleted file mode 100644 index ff2d61d..0000000 --- a/prod/Hyperion-firmware-oc/boot/oc/boot.lua +++ /dev/null @@ -1,41 +0,0 @@ -local lua = { - coroutine = true, - debug = true, - _HOST = true, - _VERSION = true, - assert = true, - collectgarbage = true, - error = true, - gcinfo = true, - getfenv = true, - getmetatable = true, - ipairs = true, - __inext = true, - load = true, - math = true, - next = true, - pairs = true, - pcall = true, - rawequal = true, - rawget = true, - rawlen = true, - rawset = true, - select = true, - setfenv = true, - setmetatable = true, - string = true, - table = true, - tonumber = true, - tostring = true, - type = true, - xpcall = true, - _G=true -} - -local apis={} -for i,v in pairs(_G) do - if not lua[i] or lua[i]==nil then - apis[i]=v - _G[i]=nil - end -end \ No newline at end of file diff --git a/prod/Hyperion-firmware-oc/boot/oc/eeprom b/prod/Hyperion-firmware-oc/boot/oc/eeprom deleted file mode 100644 index 8daa779..0000000 --- a/prod/Hyperion-firmware-oc/boot/oc/eeprom +++ /dev/null @@ -1,18 +0,0 @@ -checkArg=nil -local oldcomputer=computer -_G.computer=nil -local os=os -_G.os=nil - -function component.wrap(address) - local methods=oldcomponent.methods(address) - local object={} - for _,method in ipairs(methods) do - object[method]=function(_,...) - return oldcomponent.invoke(address,method,...) - end - end - return object -end - -local \ No newline at end of file diff --git a/prod/Hyperion-firmware-oc/boot/oc/initfs.lua b/prod/Hyperion-firmware-oc/boot/oc/initfs.lua deleted file mode 100644 index a7948ae..0000000 --- a/prod/Hyperion-firmware-oc/boot/oc/initfs.lua +++ /dev/null @@ -1 +0,0 @@ -local fs={} \ No newline at end of file diff --git a/prod/Hyperion-kernel/boot/fstab b/prod/Hyperion-kernel/boot/fstab deleted file mode 100644 index 0f7573d..0000000 --- a/prod/Hyperion-kernel/boot/fstab +++ /dev/null @@ -1,4 +0,0 @@ -U $;/ -U devfs0000;/dev/ -U tmpfs0000;/tmp/ -U procfs0000;/proc/ \ No newline at end of file diff --git a/prod/Hyperion-kernel/boot/initfs b/prod/Hyperion-kernel/boot/initfs deleted file mode 100644 index d3a154b..0000000 --- a/prod/Hyperion-kernel/boot/initfs +++ /dev/null @@ -1,84 +0,0 @@ --- :Minify:-- -local fs = {} -local disks = {} -local mounts = {} - -local function resolve(path) - local mountPoint = "/" - for mount, disk in pairs(mounts) do - if path:sub(1, #mount) == mount then - if not mountPoint or #mount > #mountPoint then - mountPoint = mount - end - end - end - local newPath = path:sub(#mountPoint + 1) - return disks[mounts[mountPoint]], newPath -end - -function fs.update(initdisks) - disks = {} - for k, v in initdisks.list() do disks[k] = v end -end - -function fs.exists(path) - local disk, newPath = resolve(path) - return disk:directoryExists(newPath) or disk:fileExists(newPath) -end - -function fs.isFile(path) - local disk, newPath = resolve(path) - return disk:fileExists(newPath) -end - -function fs.isDir(path) - local disk, newPath = resolve(path) - return disk:directoryExists(newPath) -end - -function fs.list(path) - local disk, newPath = resolve(path) - return disk:list(newPath) -end - -function fs.makeDir(path) - local disk, newPath = resolve(path) - return disk:makeDirectory(newPath) -end - -function fs.remove(path) - local disk, newPath = resolve(path) - return disk:remove(newPath) -end - -function fs.readAllText(path) - local disk, newPath = resolve(path) - local handle = disk:open(newPath, "r") - if not handle then return nil end - local content = handle.readAll() - handle.close() - return content -end - -function fs.writeAllText(path, text) - local disk, newPath = resolve(path) - local handle = disk:open(newPath, "w") - handle.write(text) - handle.close() -end - -function fs.appendAllText(path, text) - local disk, newPath = resolve(path) - local handle = disk:open(newPath, "a") - handle.write(text) - handle.close() -end - -function fs.load(path) return load(fs.readAllText(path), path) end - -function fs.mount(disk, mountPoint) - if not disks[disk] then return end - mounts[mountPoint] = disk -end - -return fs diff --git a/prod/Hyperion-kernel/boot/kernel.lua b/prod/Hyperion-kernel/boot/kernel.lua deleted file mode 100644 index edba9cd..0000000 --- a/prod/Hyperion-kernel/boot/kernel.lua +++ /dev/null @@ -1 +0,0 @@ -local a=...a.beep(440,500)local b=a.screenCtl;local c=a.initfs;local d=a.disks;local e=a.architecture;local f={}f.LOG_Text=""f.version="HyperionOS V1.2.4"f.process="Kernel"f.users={[0]="root",[1]="User"}f.hostname="hyperion"f.groups={}f.uid=0;f.gid=0;f.status="start"f.key={}f.cache={}f.cache.preload={}f._G=_G;f.sleep=sleep;_G.sleep=nil;local g=false;function f.log(h,i,j)j=j or 0x6D6D6D;f.LOG_Text=f.LOG_Text..tostring(a:date()).." "..f.users[f.uid].." "..f.process.."["..tostring(i or"INFO").."]: "..h.."\n"if f.status=="start"then b:setTextColor(j)b:print(tostring(a:date()).." "..f.users[f.uid].." "..f.process.."["..tostring(i or"INFO").."]: "..h)elseif f.status=="term"then f.standbyTask=f.currentTask;f.currentTask=f.kernelTask;local k=f.vfs.open("/dev/console","w")f.vfs.devctl(k,"sfgc",j)f.vfs.write(k,tostring(a:date()).." "..f.users[f.uid].." "..f.process.."["..tostring(i or"INFO").."]: "..h.."\n")f.vfs.close(k)f.currentTask=f.standbyTask end end;function f.PANIC(h)if f.status~="Panic"then f.log("PANIC: "..h,"PANIC",0xFF0000)pcall(f["saveLog"])f.status="Panic"f.reason=h;b:enable()b:setTextColor(0xFF0000)b:setBackgroundColor(0x000000)b:clear()b:setCursorPos(1,1)b:print(f.LOG_Text)b:print("KERNEL PANIC!\n"..h.."\nSystem halted.")b:print("Press any key to continue...")f.exitMain=true end;while true do local l={a:getMachineEvent()}if l[1]=="keyPressed"then break end end;a.reboot=true;error("KERNEL PANIC")end;f.panic=f.PANIC;if g then b:setTextColor(0xFFFFFF)b:setBackgroundColor(0x0000FF)b:clear()local m,n=b:getSize()b:setCursorPos(3,5)b:print(":(")b:setCursorPos(3,7)b:print("Your PC ran into a problem and needs to restart. We're just collecting some error")b:setCursorPos(3,8)b:print("info, and then we'll restart for you.\n")b:setCursorPos(3,n-5)b:print("Stop code: average windows experience")b:setCursorPos(1,n)b:print("Press any key to continue... jk reboot it yourself lazy")while true do end end;f.log("Kernel loaded.")f.log("Mounting init disks...")d.refresh()c.update(d)f.disks={}for o,p in d.list()do f.disks[p.address]=p end;c.mount("$","/")local q=c.readAllText("/boot/fstab")local r=function(s,t,u)assert(#t==1,"only delim len 1 supported for now")u=(u or 0)-1;local v={}local w=""for x=1,#s do local j=string.sub(s,x,x)if#v~=u and j==t then table.insert(v,w)w=""else w=w..j end end;table.insert(v,w)return v end;if not c.isFile("/boot/boot.cfg")then f.log("First boot detected writing boot.cfg","INFO",0x00FF00)c.writeAllText("/boot/boot.cfg",c.readAllText("/boot/safeboot.cfg"))f.firstBoot=true end;local y,z=load(c.readAllText("/boot/boot.cfg"),"@boot.cfg")if not y then f.PANIC("Failed to load /boot/boot.cfg: "..tostring(z))end;local A,B=pcall(y)if not A then f.PANIC("Error in /boot/boot.cfg: "..tostring(B))end;f.config=B;local C=false;for x,p in ipairs(r(q,"\n"))do if p:sub(1,1)=="U"then local D=""for x=3,#p do if p:sub(x,x)==";"then if x==3 then f.log("Invalid fstab line... Skipping.","WARN",0xFF8800)C=true;break end;D=p:sub(3,x-1)end end;if not C then local E=p:sub(#D+4)c.mount(D,E)else C=false end end end;f.log("Disks initialized")function f.saveLog()if f.status=="running"then local k=f.vfs.open("/var/log/syslog.log","w")f.vfs.write(k,f.LOG_Text)f.vfs.close(k)else c.writeAllText("/var/log/syslog.log",f.LOG_Text)end end;function f.newFifo()local F={}F.push=function(G)table.insert(F,G)end;F.pop=function()return table.remove(F,1)end;return F end;function f.newUUID()local H="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"local I=""for x=1,#H do local j=H:sub(x,x)if j=="x"then I=I..string.format("%x",math.random(0,15))elseif j=="y"then I=I..string.format("%x",math.random(8,11))else I=I..j end end;return I end;f.syscalls={}local J={[0]={}}for x=0,100 do J[x]={}end;f.log("Gathering modules")for o,x in ipairs(c.list("/lib/modules"))do local K=c.list("/lib/modules/"..x)if not K then f.log("WARNING: could not list /lib/modules/"..x.." (skipping)","WARN",0xFF8800)else for o,p in ipairs(K)do local L=tonumber(p:sub(1,2))if L then J[L+1][#J[L+1]+1]="/lib/modules/"..x.."/"..p end end end end;f.ifs=c;f.apis=a.firmware;f.EFI=a;f.arch=e;f.initdisks=d;f.screen=b;f.processes={}f.fstab=q;f.kernelTask={name="kernel",status="R",pid=0,tgid=0,uid=0,fd={},exit="",sleep=0,ivs=0,vs=0,children={},syscallReturn={},cwd="/",timeSlice=0,lastTime=0,totalTime=0,numRuns=0}f.currentTask=f.kernelTask;function f.shutdown()f.exitMain=true;f.status="shutdown"end;function f.reboot()f.exitMain=true;f.status="reboot"end;f.syscalls["time"]=function()return f.EFI:getEpochMs()end;f.syscalls["date"]=function()return f.EFI:date()end;f.syscalls["log"]=f.log;f.syscalls["getUptime"]=function()return f.EFI:getUptime()end;f.syscalls["getUsername"]=function(M)return f.users[M or f.uid]end;f.syscalls["getHostname"]=function()return f.hostname end;f.syscalls["getHost"]=function()return f.apis._HOST end;f.syscalls["version"]=function()return f.version end;f.syscalls["setHostname"]=function(N)if f.uid~=0 then error("Permission denied")end;f.hostname=N end;f.syscalls["arch"]=function()return e end;f.syscalls["sysdump"]=function()local v={}for x,p in pairs(f.syscalls)do v[#v+1]=x end;return v end;f.syscalls["reboot"]=f.reboot;f.syscalls["shutdown"]=f.shutdown;f.log("Running modules")for o,O in ipairs(J)do for o,p in ipairs(O)do if f.config.showModLoad then f.log("Loading module "..p,"DBUG",0x00FFFF)end;local P=c.readAllText(p)if not P then f.panic("Failed to read module "..p)end;local Q,z=load(P,"@"..p)if not Q then f.panic("ModuLoadErr: "..tostring(z))end;local R,z=xpcall(Q,debug.traceback,f)if not R then f.panic("ModuRunErr: "..tostring(z))end;if f.config.showModLoad then f.log("Loaded module "..p,"DBUG",0x00FFFF)end end end;f.log("Kernel initialized successfully.")f.saveLog()f.status="running"b:disable()f.main()if f.status=="panic"then f.panic(f.reason)end;if f.status=="reboot"then a.reboot=true;return true end diff --git a/prod/Hyperion-kernel/boot/safeboot.cfg b/prod/Hyperion-kernel/boot/safeboot.cfg deleted file mode 100644 index 1c58e65..0000000 --- a/prod/Hyperion-kernel/boot/safeboot.cfg +++ /dev/null @@ -1,12 +0,0 @@ --- DO NOT EDIT THIS FILE IF YOU DO NOT KNOW WHAT YOU ARE DOING! --- DOING SO MAY RENDER YOUR SYSTEM UNBOOTABLE! - --- This file is auto-generated during the build process. --- DEFAULT BOOT CONFIGURATION FILE -return { - initPath = "/sbin/init", - maxOpenFiles = 128, - maxFilesPerTask = 16, - preempt=true, - logTaskExit=true -} \ No newline at end of file diff --git a/prod/Hyperion-kernel/etc/passwd b/prod/Hyperion-kernel/etc/passwd deleted file mode 100644 index 434ccc5..0000000 --- a/prod/Hyperion-kernel/etc/passwd +++ /dev/null @@ -1 +0,0 @@ -0:0:root:/root:/bin/hysh \ No newline at end of file diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/01_stdlib.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/01_stdlib.kmod deleted file mode 100644 index 3d9b187..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/01_stdlib.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...a.allowGlobalOverwrites=true;function string.hasSuffix(b,c)return string.sub(b,#c+1)==c end;function string.hasPrefix(b,d)return string.sub(b,1,#d)==d end;function string.getSuffix(b,d)return string.sub(b,#d+1)end;function string.getPrefix(b,c)return string.sub(b,1,#c)end;function string.join(b,...)return table.concat(table.pack(b,...))end;function string.delim(b,...)return table.concat(table.pack(...),b)end;function string.split(b,e,f)assert(#e==1,"only delim len 1 supported for now")if not b then return false end;f=(f or 0)-1;local g={}local h=""for i=1,#b do local j=string.sub(b,i,i)if#g~=f and j==e then table.insert(g,h)h=""else h=h..j end end;table.insert(g,h)return g end;function table.deepcopy(k,l)l=l or{}if type(k)~='table'then return k elseif l[k]then return l[k]end;local m={}l[k]=m;for n,o in next,k,nil do local p=table.deepcopy(n,l)local q=table.deepcopy(o,l)m[p]=q end;return m end;function table.hasKey(r,s)for i,o in pairs(r)do if i==s then return o end end;return false end;function table.hasVal(r,s)for i,o in pairs(r)do if o==s then return i end end;return false end;local function t(u,v)v=v or{}if v[u]then return'"[Circular Reference]"'end;v[u]=true;local w="{"local x=true;for i,o in pairs(u)do if not x then w=w..","end;x=false;if type(i)=="string"then w=w.."[\""..i.."\"]="elseif type(i)=="number"then w=w.."["..tostring(i).."]="end;if type(o)=="table"then w=w..t(o,v)elseif type(o)=="string"then w=w.."[=["..o.."]=]"elseif type(o)=="number"or type(o)=="boolean"then w=w..tostring(o)elseif type(o)=="function"then w=w.."\""..tostring(o).."\""elseif type(o)=="thread"then w=w.."\""..tostring(o).."\""else error("serialization of type \""..type(o).."\" is not supported")end end;v[u]=nil;w=w.."}"return w end;local y=type;local z=getmetatable;function type(A,B)if B then return y(A)end;if y(A)~="table"then return y(A)else if y(z(A))=="table"then local C=z(A)if C.__type then return C.__type end else return"table"end end end;function getmetatable(A)if y(A)~="table"then return end;if y(z(A))=="table"then if z(A).__isuserdata then if y(z(A).__usermeta)=="function"then return z(A).__usermeta()else return z(A).__usermeta end else return z(A)end else return z(A)end end;function isEqualToAny(D,...)local E={...}for i=0,#E do if D==E[i]then return true end end;return false end;function isEqualToAll(D,...)local E={...}for i=0,#E do if D~=E[i]then return false end end;return true end;function table.keys(F)local D={}for G in pairs(F)do table.insert(D,G)end;return D end;function table.values(F)local D={}for H,G in pairs(F)do table.insert(D,G)end;return D end;function table.indexOf(F,I)for i,o in ipairs(F)do if o==I then return i end end;return-1 end;function table.merge(...)local E={...}local J={}local K={}for H,F in ipairs(E)do for i,o in pairs(F)do J[i]=o end;for i,o in ipairs(F)do K[#K+1]=o end end;for i,o in ipairs(K)do J[i]=o end;return J end;function string.replace(L,M,N)local O={}local i=1;local G=#L;local P=#M;while i<=G do local Q=true;if i+P-1<=G then for R=1,P do if L:sub(i+R-1,i+R-1)~=M:sub(R,R)then Q=false;break end end else Q=false end;if Q then table.insert(O,N)i=i+P else table.insert(O,L:sub(i,i))i=i+1 end end;return table.concat(O)end;function toHex(S)return string.format("%X",S)end;local function T()local U={}return setmetatable(U,{__index=function(self,V)local W=rawget(self,V)if W~=nil then return W end;return function(...)local X=table.pack(coroutine.yield("syscall",V,...))if X[1]then return table.unpack(X,2,X.n)else error(X[2],2)end end end,__newindex=function(self,n,o)rawset(self,n,o)end,__metatable=false})end;syscall=T()_makeSyscallProxy=T;table.serialize=t diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/10_vfs.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/10_vfs.kmod deleted file mode 100644 index 45719ac..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/10_vfs.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b={}a.vfs=b;b.mounts={["$"]="/"}b.disks=a.disks;local c=0x02;local function d(e,f)return math.floor(e/2^f)%2==1 end;local function g(h)if not h or h==""then return{}end;local i={}local j=1;local k=0;local l=h:byte(1)if l==0x02 or l==0x01 then k=l;j=2 end;while j<=#h do if j>#h then break end;local m=h:byte(j)j=j+1;if m==0 or j+m-1>#h then break end;local n=h:sub(j,j+m-1)j=j+m;local o,p,q,r,s;if k==0x02 then if j+6>#h then break end;o=h:byte(j)j=j+1;p=h:byte(j)+h:byte(j+1)*256;j=j+2;q=h:byte(j)+h:byte(j+1)*256;j=j+2;r=h:byte(j)+h:byte(j+1)*256;j=j+2 elseif k==0x01 then if j+4>#h then break end;o=h:byte(j)j=j+1;p=h:byte(j)j=j+1;q=h:byte(j)j=j+1;r=h:byte(j)+h:byte(j+1)*256;j=j+2 else if j+2>#h then break end;o=0x00;p=h:byte(j)j=j+1;q=h:byte(j)j=j+1;r=h:byte(j)j=j+1 end;if j>#h then break end;local t=h:byte(j)j=j+1;s=""if t>0 then s=h:sub(j,j+t-1)j=j+t end;i[n]={etype=o,owner=p,group=q,perms=r,cmeta=s}end;return i end;local function u(v)local w=string.char(c)for n,x in pairs(v)do local y=x.perms%256;local z=math.floor(x.perms/256)%256;local A=(x.owner or 0)%256;local B=math.floor((x.owner or 0)/256)%256;local C=(x.group or 0)%256;local D=math.floor((x.group or 0)/256)%256;w=w..string.char(#n)..n..string.char(x.etype or 0x00)..string.char(A,B,C,D,y,z)..string.char(#x.cmeta)..x.cmeta end;return w end;local E="^[A-Za-z0-9_.+%-%@%(%)%[%]]+$"local function F(G)local H=G:sub(1,1)=="/"local I={}for J in(G.."/"):gmatch("([^/]*)/")do table.insert(I,J)end;return H,I end;local function K(J)local L=J:lower()if not L:match(E)then error("EINVAL: illegal characters in path component: "..J,3)end;if L==".meta"then error("EINVAL: reserved path component: .meta",3)end end;function b.splitPath(G)local M=string.split(G,"/")while table.indexOf(M,"")~=-1 do table.remove(M,table.indexOf(M,""))end;return M end;local function N(O)local P,Q=nil,nil;for R,S in pairs(b.mounts)do local T=S~="/"and S:sub(-1)=="/"and S:sub(1,-2)or S;if O==T or T=="/"and O:sub(1,1)=="/"or O:sub(1,#T+1)==T.."/"then if not P or#T>#P then P=T;Q=R end end end;if not Q then error("ENODEV")end;local U=O:sub(#P+1)if U==""then U="/"end;return b.disks[Q],U end;b._parseMetafile=g;local function V(W,X,Y)if Y==".meta"then error("EACCES: Cannot open metafile")end;local S;if X=="/"then S=".meta"else local j=X:gsub("^/+","")S=j.."/.meta"end;local Z,_=pcall(function()return W:open(S,"r")end)if not Z or not _ then return nil end;local h=_.read(65535)if _.close then _.close()end;if h and#h>0 and h:byte(1)~=c then local a0=u(g(h))local a1,a2=pcall(function()return W:open(S,"w")end)if a1 and a2 then a2.write(a0)if a2.close then a2.close()end end;h=a0 end;local a3=g(h)return a3[Y]end;local a4=16;local function a5(G,a6,a7)a7=a7 or 0;if a7>a4 then error("ELOOP")end;local a8=a.currentTask;local a9=a8 and(a8.euid or a8.uid)or a.uid;local aa=a8 and a8.groups or a.groups or{}local ab=a8 and a8.root or"/"local ac=a8 and a8.cwd or"/"if ab~="/"and ab:sub(-1)=="/"then ab=ab:sub(1,-2)end;local function ad(ae)if a9==0 then return true end;if not ae then return true end;local af=ae.perms;if a9==ae.owner and d(af,9)then return true end;if ae.group then for ag,ah in ipairs(aa)do if ah==ae.group and d(af,8)then return true end end end;return d(af,7)end;local H,I=F(G)local ai={}if H then ai={}else for aj in ac:gmatch("[^/]+")do table.insert(ai,aj)end end;local ak=1;while ak<=#I do local J=I[ak]ak=ak+1;J=J:match("^%s*(.-)%s*$")if J==""or J=="."then elseif J==".."then local al="/"..table.concat(ai,"/")local am={}if ab~="/"then for aj in ab:gmatch("[^/]+")do table.insert(am,aj)end end;if#ai<=#am then ai={}for ag,aj in ipairs(am)do table.insert(ai,aj)end else local an=ai[#ai]local ao="/"..table.concat(ai,"/",1,#ai-1)if ao=="/"then ao="/"end;local ap,aq,ar=pcall(N,ao==""and"/"or ao)if ap and aq then local ae=V(aq,ar,an)if ae then if ae.etype~=0x00 then error("ENOTDIR: not a directory: "..al)end;if not ad(ae)then error("EACCES: permission denied traversing "..al)end else local as,at,au=pcall(N,al)if as and at then local av=at:type(au)if av~=nil and av~="directory"then error("ENOTDIR: not a directory: "..al)end end end end;table.remove(ai)end else K(J)local aw=J:lower()local ax="/"..table.concat(ai,"/")local ap,aq,ar=pcall(N,ax=="/"and"/"or ax)local ae=nil;if ap and aq then ae=V(aq,ar,aw)end;local ay=ak>#I;if ae and ae.etype==0x01 then if ay and a6 then table.insert(ai,aw)else a7=a7+1;if a7>a4 then error("ELOOP")end;local az=ae.cmeta;if not az or az==""then error("ENOENT: empty symlink target")end;local aA,aB=F(az)if aA then ai={}if ab~="/"then for aj in ab:gmatch("[^/]+")do table.insert(ai,aj)end end end;local aC={}for aD=1,ak-2 do table.insert(aC,I[aD])end;local aE=#aC+1;for ag,aF in ipairs(aB)do table.insert(aC,aF)end;for aD=ak,#I do table.insert(aC,I[aD])end;I=aC;ak=aE end else table.insert(ai,aw)if not ay then local aG="/"..table.concat(ai,"/")local as,at,au=pcall(N,aG)if as and at then local av=at:type(au)if av~=nil and av~="directory"then error("ENOTDIR: not a directory: "..aG)end end;if not ad(ae)then error("EACCES: permission denied traversing "..aG)end end end end end;local aH="/"..table.concat(ai,"/")if ab~="/"then if aH~=ab and aH:sub(1,#ab+1)~=ab.."/"then aH=ab end end;return aH end;local function aI(G)local a8=a.currentTask;local ac=a8 and a8.cwd or"/"local ab=a8 and a8.root or"/"if ab~="/"and ab:sub(-1)=="/"then ab=ab:sub(1,-2)end;local H,I=F(G)local ai={}if not H then for aj in ac:gmatch("[^/]+")do table.insert(ai,aj)end end;local am={}if ab~="/"then for aj in ab:gmatch("[^/]+")do table.insert(am,aj)end end;for ag,J in ipairs(I)do J=J:match("^%s*(.-)%s*$")if J==""or J=="."then elseif J==".."then if#ai>#am then table.remove(ai)end else table.insert(ai,J:lower())end end;local aH="/"..table.concat(ai,"/")if ab~="/"then if aH~=ab and aH:sub(1,#ab+1)~=ab.."/"then aH=ab end end;return aH end;local function aJ(G,a6)local aK=a5(G,a6)local W,U=N(aK)if a.config.logPathResolution then a.log("resolvePath '"..G.."' -> '"..aK.."' diskPath '"..U.."'")end;return W,U,aK end;local function aL(G,a6)local aK=a5(G,a6)if aK=="/"then return{etype=0x00,owner=0,group=0,perms=62,cmeta=""}end;local aM=aK;while true do local aN,n=aM:match("^(.*)/([^/]+)$")if not aN or aN==""then aN="/"end;local W,X=N(aN)local ae=V(W,X,n)if ae then return ae end;if aN=="/"or aM=="/"then break end;aM=aN end;return{etype=0x00,owner=0,group=0,perms=63,cmeta=""}end;local function aO(G,n,ae,a6)local aK=a5(G,a6)local W,U=N(aK)local S;if U=="/"then S=".meta"else S=U:gsub("^/+","").."/.meta"end;local aP={}local aQ,aR=pcall(function()return W:open(S,"r")end)if aQ and aR then local h=aR.read(65535)if aR.close then aR.close()end;aP=g(h)end;aP[n]=ae;local _=W:open(S,"w")_.write(u(aP))if _.close then _.close()end end;b.P={OWNER_R=1*2^5,OWNER_W=1*2^4,OWNER_X=1*2^9,GROUP_R=1*2^3,GROUP_W=1*2^2,GROUP_X=1*2^8,WORLD_R=1*2^1,WORLD_W=1*2^0,WORLD_X=1*2^7,SUID=1*2^6}local aS=b.P;b.PERM={RW_R_R=aS.OWNER_R+aS.OWNER_W+aS.GROUP_R+aS.WORLD_R,RWX_RX=aS.OWNER_R+aS.OWNER_W+aS.OWNER_X+aS.GROUP_R+aS.GROUP_X+aS.WORLD_R+aS.WORLD_X,RW_R__=aS.OWNER_R+aS.OWNER_W+aS.GROUP_R,RW____=aS.OWNER_R+aS.OWNER_W,RWXR__=aS.OWNER_R+aS.OWNER_W+aS.OWNER_X+aS.GROUP_R+aS.WORLD_R,SUID_755=aS.SUID+aS.OWNER_R+aS.OWNER_W+aS.OWNER_X+aS.GROUP_R+aS.GROUP_X+aS.WORLD_R+aS.WORLD_X,RWXRWXRWX=aS.OWNER_R+aS.OWNER_W+aS.OWNER_X+aS.GROUP_R+aS.GROUP_W+aS.GROUP_X+aS.WORLD_R+aS.WORLD_W+aS.WORLD_X}local function aT(v,aU)local a8=a.currentTask;local a9=a8 and a8.euid or a8 and a8.uid or a.uid;local aa=a8 and a8.groups or a.groups or{}if a9==0 then return true end;local af=v.perms;if aU=="x"then if a9==v.owner and d(af,9)then return true end;if v.group then for ag,ah in ipairs(aa)do if ah==v.group and d(af,8)then return true end end end;if d(af,7)then return true end;error("EACCES")end;local aV={r={owner=5,group=3,everyone=1},w={owner=4,group=2,everyone=0},a={owner=4,group=2,everyone=0}}local x=aV[aU]if not x then error("EINVAL")end;if a9==v.owner and d(af,x.owner)then return true end;if v.group then for ag,ah in ipairs(aa)do if ah==v.group and d(af,x.group)then return true end end end;if d(af,x.everyone)then return true end;error("EACCES")end;local function aW(G)G=aI(G)if G~="/"and G:sub(-1)=="/"then G=G:sub(1,-2)end;return G end;local aX={"open","type","list","attributes","fileExists","makeDirectory","remove"}local function aY(W)for ag,n in ipairs(aX)do if type(W[n])~="function"then error("Invalid disk: missing method '"..n.."'")end end end;local aZ=0;local function a_(a8)local b0=0;while a8.fd[b0]do b0=b0+1 end;if b0>=a.config.maxFilesPerTask then error("ENFILE")end;return b0 end;local function b1()if aZ>=a.config.maxOpenFiles-16 then error("ENFILE")end end;local function b2(b3,aU,G,v,b4)return{handle=b3,mode=aU,path=G,meta=v,type=b4,refcount=1}end;function b.newfd(b5)local b0=a_(a.currentTask)a.currentTask.fd[b0]=b5;return b0 end;function b.mount(az,b6)local b7=a.currentTask and(a.currentTask.euid or a.currentTask.uid)or a.uid;if b7~=0 then error("EPERM")end;if not az then error("EINVAL")end;az=aW(az)local b8,G=aJ(az)if not b8:directoryExists(G)then b8:makeDirectory(G)end;if b8:type(az)~="directory"then error("EINVAL")end;local W,R;if type(b6)=="string"then W=a.disks[b6]if not W then error("ENODEV")end;aY(W)R=b6 elseif type(b6)=="table"then aY(b6)W=b6;R=W.address;b.disks[R]=W else error("EINVAL")end;if b.mounts[R]then error("EBUSY")end;for ag,S in pairs(b.mounts)do if S==az then error("EBUSY")end end;b.mounts[R]=az;return true end;function b.umount(az)local b7=a.currentTask and(a.currentTask.euid or a.currentTask.uid)or a.uid;if b7~=0 then error("EPERM")end;if not az then error("EINVAL")end;az=aW(az)for R,S in pairs(b.mounts)do if S==az then if R=="$"then error("EBUSY")end;b.mounts[R]=nil;return true end end;error("EINVAL")end;function b.open(G,aU)b1()local a8=a.currentTask;local b0=a_(a8)local W,U=aJ(G)if not W then error("NODISK")end;if(aU=="w"or aU=="a")and W:isReadOnly()then error("ERDONLY")end;if a.unixSockets[aI(G)]then local v=a.unixSockets[aI(G)].meta;if a.uid~=0 or a.uid~=v.owner then local aa=a8 and a8.groups or a.groups or{}local b9=false;for ag,ah in ipairs(aa)do if ah==v.group then b9=true end end;if not b9 then error("EACCES")end end;a8[b0]=a.unixSockets[aI(G)]return b0 end;local v=aL(G)local ba=(aU=="w"or aU=="a")and not W:fileExists(U)aT(v,aU=="r"and"r"or"w")local b3;if W:type(U)~="directory"then b3=W:open(U,aU)if type(b3)~="table"then error("ENFILE")end end;if ba then local a9=a8 and(a8.euid or a8.uid)or a.uid;local bb=a8 and a8.gid or 0;local bc=aI(G)local aN=bc:match("^(.*)/[^/]+$")or"/"if aN==""then aN="/"end;local n=bc:match("[^/]+$")if n then local ae={etype=0x00,owner=a9,group=bb,perms=b.PERM.RW_R_R,cmeta=""}pcall(aO,aN,n,ae,false)v=ae end end;local bd=b2(b3,aU,G,v,W:type(U))if aU=="r"and d(v.perms,6)then bd.suid_owner=v.owner end;if W.isvirt then bd.isvirt=true end;a8.fd[b0]=bd;if not W.isvirt then aZ=aZ+1 end;return b0 end;function b.read(b0,be)local bf=a.currentTask.fd[b0]if not bf or not bf.handle or not bf.handle.read then error("EBADF")end;return bf.handle.read(be or 1)or""end;function b.write(b0,bg)local bf=a.currentTask.fd[b0]if not bf or not bf.handle or not bf.handle.write then error("EBADF")end;return bf.handle.write(bg)end;function b.pread(b0,be,bh)local bf=a.currentTask.fd[b0]if not bf or not bf.handle or not bf.handle.read or not bf.handle.seek then error("EBADF")end;bf.handle.seek("set",bh)return bf.handle.read(be or 1)or""end;function b.pwrite(b0,bg,bh)local bf=a.currentTask.fd[b0]if not bf or not bf.handle or not bf.handle.write or not bf.handle.seek then error("EBADF")end;bf.handle.seek("set",bh)return bf.handle.write(bg)end;function b.lseek(b0,bh,bi)local bf=a.currentTask.fd[b0]if not bf or not bf.handle or not bf.handle.seek then error("EBADF")end;return bf.handle.seek(bi or"set",bh)end;function b.fsync(b0)local bf=a.currentTask.fd[b0]if not bf or not bf.handle or not bf.handle.flush then error("EBADF")end;if bf.mode~="w"and bf.mode~="a"then error("EBADF")end;bf.handle.flush()end;function b.close(b0)local a8=a.currentTask;local bf=a8.fd[b0]if not bf then error("EBADF")end;if not a8.fd[b0].isvirt then aZ=aZ-1 end;a8.fd[b0]=nil;bf.refcount=bf.refcount-1;if bf.refcount<=0 and bf.handle and bf.handle.close then bf.handle.close()end end;function b.sendfile(bj,bk,be)local bl=a.currentTask.fd[bk]local bm=a.currentTask.fd[bj]if not bl or not bm then error("EBADF")end;if not bl.handle.read or not bm.handle.write then error("EBADF")end;local bn=bl.handle.read(be or 1024)if not bn or bn==""then return end;return bm.handle.write(bn)end;function b.stat(G)local bo;local v;if v.etype==0x02 then bo={size=0,modified=0,created=0}else local W,U=aJ(G)v=aL(G)local Z;Z,bo=pcall(W.attributes,W,U)if not Z then bo={size=0,modified=0,created=0}end end;return{size=bo.size,modified=bo.modified,created=bo.created,owner=v.owner,group=v.group,perms=v.perms,etype=v.etype,xattr=v.cmeta}end;function b.lstat(G)local v=aL(G,true)local bo;if v.etype==0x01 or v.etype==0x02 then bo={size=0,modified=0,created=0}else local W,U=aJ(G,true)local Z,bp=pcall(W.attributes,W,U)bo=Z and bp or{size=0,modified=0,created=0}end;return{size=bo.size,modified=bo.modified,created=bo.created,owner=v.owner,group=v.group,perms=v.perms,etype=v.etype,xattr=v.etype==0x01 and""or v.cmeta,symlink_target=v.etype==0x01 and v.cmeta or nil}end;function b.fstat(b0)local bf=a.currentTask.fd[b0]if not bf then error("EBADF")end;local bo;if bf.meta.etype==0x02 then bo={size=0,modified=0,created=0}else local W,U=aJ(bf.path,true)local Z,bp=pcall(W.attributes,W,U)bo=Z and bp or{size=0,modified=0,created=0}end;return{size=bo.size,modified=bo.modified,created=bo.created,owner=bf.meta.owner,group=bf.meta.group,perms=bf.meta.perms,etype=bf.meta.etype,xattr=bf.meta.cmeta}end;function b.listdir(G)local W,U=aJ(G)local v=aL(G)aT(v,"r")if W:type(U)~="directory"then error("ENOTDIR")end;local bq=W:list(U)local br={}local w={}for ag,bs in ipairs(bq)do if bs~=".meta"then br[bs]=true;table.insert(w,bs)end end;for bt,bs in pairs(a.unixSockets)do local j=aI(G)if bt:match("^(.*)/[^/]+$")==j then br[bs.name]=true;table.insert(w,bs.name)end end;local S;if U=="/"then S=".meta"else S=U:gsub("^/+","").."/.meta"end;local bu,bv=pcall(function()return W:open(S,"r")end)if bu and bv then local h=bv.read(65535)if bv.close then bv.close()end;local a3=g(h)for n,ae in pairs(a3)do if ae.etype==0x01 and not br[n]then table.insert(w,n)end end end;return w end;function b.mkdir(G)local bc=aI(G)local aN=bc:match("^(.*)/[^/]+$")or"/"if aN==""then aN="/"end;local bw=aL(aN)aT(bw,"w")local W,U=aJ(G)if W:isReadOnly()then error("ERDONLY")end;W:makeDirectory(U)local a8=a.currentTask;local a9=a8 and(a8.euid or a8.uid)or a.uid;local bb=a8 and a8.gid or 0;local n=bc:match("[^/]+$")if n then local ae={etype=0x00,owner=a9,group=bb,perms=b.PERM.RWX_RX,cmeta=""}pcall(aO,aN,n,ae,false)end end;function b.remove(G)local bc=a5(G,true)local aN=bc:match("^(.*)/[^/]+$")or"/"if aN==""then aN="/"end;local bw=aL(aN)aT(bw,"w")local v=aL(G,true)if a.unixSockets and a.unixSockets[aI(G)]then if a.uid~=0 then if a.unixSockets[aI(G)].meta.owner~=a.uid then error("EACCES")end end;a.unixSockets[aI(G)]=nil end;if v.etype==0x01 then local bc=a5(G,true)local aN=bc:match("^(.*)/[^/]+$")or"/"if aN==""then aN="/"end;local n=bc:match("[^/]+$")local W,X=N(aN)if W:isReadOnly()then error("ERDONLY")end;local S;if X=="/"then S=".meta"else S=X:gsub("^/+","").."/.meta"end;local aQ,aR=pcall(function()return W:open(S,"r")end)local a3={}if aQ and aR then local h=aR.read(65535)if aR.close then aR.close()end;a3=g(h)end;a3[n]=nil;local bx=W:open(S,"w")bx.write(u(a3))if bx.close then bx.close()end else local W,U=aJ(G)if W:isReadOnly()then error("ERDONLY")end;W:remove(U)end end;function b.symlink(az,by)if type(az)~="string"or type(by)~="string"then error("EINVAL")end;local bc=aI(by)local aN=bc:match("^(.*)/[^/]+$")or"/"local W=N(by)if W:isReadOnly()then error("ERDONLY")end;if aN==""then aN="/"end;local n=bc:match("[^/]+$")if not n then error("EINVAL")end;local bw=aL(aN)aT(bw,"w")local a8=a.currentTask;local a9=a8 and(a8.euid or a8.uid)or a.uid;local bb=a8 and a8.gid or a.gid or 0;local ae={etype=0x01,owner=a9,group=bb,perms=b.PERM.RWXRWXRWX,cmeta=az}local Z,bz=pcall(aO,aN,n,ae,false)if not Z then error(bz)end end;function b.readlink(G)local v=aL(G,true)if v.etype~=0x01 then error("EINVAL")end;return v.cmeta end;function b.access(G,aU)local v;if a.unixSockets[aI(G)]then v=a.unixSockets[aI(G)].meta else v=aL(G)end;for ak=1,#aU do aT(v,aU:sub(ak,ak))end;return true end;local function bA(G,bB,a6)local aK=a5(G,a6)local bc=aK;local aN=bc:match("^(.*)/[^/]+$")or"/"local W=N(G)if W:isReadOnly()then error("ERDONLY")end;if aN==""then aN="/"end;local n=bc:match("[^/]+$")if not n then error("EINVAL")end;local W,bC=N(aN)local S;if bC=="/"then S=".meta"else S=bC:gsub("^/+","").."/.meta"end;local aP={}local bD,bE=pcall(function()return W:open(S,"r")end)if bD and bE then local h=bE.read(65535)if bE.close then bE.close()end;aP=g(h)end;local ae=aP[n]or{etype=0,owner=0,group=0,perms=63,cmeta=""}bB(ae)aP[n]=ae;local _=W:open(S,"w")_.write(u(aP))if _.close then _.close()end end;function b.chmod(G,r)if a.unixSockets[aI(G)]then error("EINVAL")end;local W=N(G)if W:isReadOnly()then error("ERDONLY")end;local v=aL(G)local a9=a.currentTask and(a.currentTask.euid or a.currentTask.uid)or a.uid;if a9~=0 and a9~=v.owner then error("EACCES")end;bA(G,function(bF)bF.perms=r end)end;function b.fchmod(b0,r)local bf=a.currentTask.fd[b0]if not bf then error("EBADF")end;if bf.etype==0x02 then error("EINVAL")end;b.chmod(bf.path,r)end;function b.chown(G,bG,ah)if a.unixSockets[aI(G)]then error("EINVAL")end;local W=N(G)if W:isReadOnly()then error("ERDONLY")end;local b7=a.currentTask and(a.currentTask.euid or a.currentTask.uid)or a.uid;if b7~=0 then error("EPERM")end;bA(G,function(bF)bF.owner=bG;bF.group=ah end)end;function b.fchown(b0,bG,ah)local bf=a.currentTask.fd[b0]if not bf then error("EBADF")end;if bf.etype==0x02 then error("EINVAL")end;b.chown(bf.path,bG,ah)end;function b.exists(G)if a.unixSockets[aI(G)]then return true end;local v=aL(G,true)if v.etype==0x01 then return true end;local Z,W,U=pcall(aJ,G)if not Z then return false end;if W:type(U)then return true else return false end end;function b.type(G)local v=aL(G,true)if v.etype==0x01 then return"symlink"end;if a.unixSockets[aI(G)]then return"socket"end;local Z,W,U=pcall(aJ,G)if not Z then return nil end;return W:type(U)end;function b.getcwd()return a.currentTask.cwd end;function b.chdir(G)if b.type(G)~="directory"then error("ENOTDIR")end;a.currentTask.cwd=aI(G)end;function b.chroot(G)local a9=a.currentTask and(a.currentTask.euid or a.currentTask.uid)or a.uid;if a9~=0 then error("EPERM")end;if b.type(G)~="directory"then error("ENOTDIR")end;local bc=aI(G)a.currentTask.root=bc;a.currentTask.cwd=bc end;function b.dup(bH)local a8=a.currentTask;local bf=a8.fd[bH]if not bf then error("EBADF")end;b1()local bI=a_(a8)bf.refcount=bf.refcount+1;a8.fd[bI]=bf;aZ=aZ+1;return bI end;function b.dup2(bH,bI)local a8=a.currentTask;local bf=a8.fd[bH]if not bf then error("EBADF")end;if bI<0 or bI>=a.config.maxFilesPerTask then error("EBADF")end;if bH==bI then return bI end;if a8.fd[bI]then b.close(bI)end;b1()bf.refcount=bf.refcount+1;a8.fd[bI]=bf;aZ=aZ+1;return bI end;function b.devctl(b0,bJ,...)if not a.currentTask.fd[b0]then error("EBADF")end;if not a.currentTask.fd[b0].handle[bJ]then error("EINVAL")end;return a.currentTask.fd[b0].handle[bJ](...)end;b.resolveMount=N;local bK=a.syscalls;bK["open"]=b.open;bK["close"]=b.close;bK["read"]=b.read;bK["write"]=b.write;bK["pread"]=b.pread;bK["pwrite"]=b.pwrite;bK["lseek"]=b.lseek;bK["fsync"]=b.fsync;bK["sendfile"]=b.sendfile;bK["stat"]=b.stat;bK["lstat"]=b.lstat;bK["fstat"]=b.fstat;bK["mkdir"]=b.mkdir;bK["remove"]=b.remove;bK["listdir"]=b.listdir;bK["chmod"]=b.chmod;bK["fchmod"]=b.fchmod;bK["chown"]=b.chown;bK["fchown"]=b.fchown;bK["exists"]=b.exists;bK["type"]=b.type;bK["mount"]=b.mount;bK["umount"]=b.umount;bK["getcwd"]=b.getcwd;bK["chdir"]=b.chdir;bK["chroot"]=b.chroot;bK["dup"]=b.dup;bK["dup2"]=b.dup2;bK["devctl"]=b.devctl;bK["symlink"]=b.symlink;bK["readlink"]=b.readlink;bK["access"]=b.access;bK["fget_suid"]=function(b0)local bd=a.currentTask and a.currentTask.fd[b0]return bd and bd.suid_owner or nil end;a.log("VFS module loaded") diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/11_require.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/11_require.kmod deleted file mode 100644 index e232d03..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/11_require.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b={}a.searchpaths={"/lib/?.lua","/lib/?","/usr/lib/?.lua","/usr/lib/?","/usr/local/lib/?.lua","/usr/local/lib/?","?.lua","?"}function require(c,...)if b[c]then return b[c]end;local d=c:gsub("%.","/")local e={}for f,g in ipairs(a.searchpaths)do local h=string.replace(g,"?",d)if h:sub(1,1)~="/"then h=a.currentTask.cwd..h end;if a.vfs.exists(h)then if a.vfs.type(h)=="directory"then h=h.."/init"end;if a.vfs.exists(h)then local i=a.vfs.open(h,"r")local j=a.vfs.read(i,1024*1024*4)a.vfs.close(i)return assert(load(j,h,"t",a._U))(...)else table.insert(e,h)end else table.insert(e,h)end end;error("Module not found: "..c.." (searched paths: "..table.concat(e,", ")..")")end diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/12_devfs.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/12_devfs.kmod deleted file mode 100644 index 83dbc7f..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/12_devfs.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b={}local c={}b.address="devfs0000"b.isvirt=true;b.isReadOnly=function()return false end;b.spaceUsed=function()return 0 end;b.spaceTotal=function()return 0 end;b.makeDirectory=function()error("EACCES")end;b.remove=function()error("EACCES")end;b.setLabel=function()error("EACCES")end;b.getLabel=function()return"devfs"end;b.attributes=function(d)return{size=0,modified=0,created=0}end;function b:open(d,e)local f=a.vfs.splitPath(d)local g=c;for h=1,#f-1 do local i=g[f[h]]if type(i)~="table"then error("ENFILE")end;g=i end;if type(g[f[#f]])=="function"then return g[f[#f]]("open",e)end;error("ENFILE")end;function b:type(d,e)local f=a.vfs.splitPath(d)local g=c;if#f==0 then return"directory"end;for h=1,#f-1 do local i=g[f[h]]if type(i)~="table"then error("ENFILE")end;g=i end;if type(g[f[#f]])=="function"then return g[f[#f]]("type",e)end;if type(g[f[#f]])=="table"then return"directory"end;error(type(g[f[#f]]))end;function b:list(d)local f=a.vfs.splitPath(d)local g=c;if#f==0 then return table.keys(c)end;for h=1,#f-1 do local i=g[f[h]]if type(i)~="table"then error("ENOENT")end;g=i end;if type(g[f[#f]])=="table"then return table.keys(g[f[#f]])end;error("ENOENT")end;function b:fileExists(d)local j=pcall(function()return self:type(d)end)return j end;function c.random(k,e)if k=="type"then return"character device"elseif k=="open"then if e=="r"then return{read=function(l)local m=""for h=1,l or 1 do m=m..string.char(math.random(0,255))end;return m end}elseif e=="w"or e=="a"then return{write=function()end}else error("EACCES")end end end;function c.null(k,e)if k=="type"then return"character device"elseif k=="open"then if e=="r"then return{read=function(l)end}elseif e=="w"or e=="a"then return{write=function()end}else error("EACCES")end end end;function c.zero(k,e)if k=="type"then return"character device"elseif k=="open"then if e=="r"then return{read=function(l)local m=""for h=1,l or 1 do m=m..string.char(0)end;return m end}elseif e=="w"or e=="a"then return{write=function()end}else error("EACCES")end end end;if a.EFI:getEEPROM()then function c.eeprom(k,e)if k=="type"then return"character device"elseif k=="open"then if e=="r"then local n,o=1,a.EFI:getEEPROM()return{read=function(l)n=n+l;return o:sub(n-l,n)end}elseif e=="w"then if a.uid~=0 then error("EACCES")end;local p=true;return{write=function(c)if p then a.EFI:setEEPROM(c)else a.EFI:setEEPROM(a.EFI:getEEPROM()..c)end end}elseif e=="a"then if a.uid~=0 then error("EACCES")end;return{write=function(c)a.EFI:setEEPROM(a.EFI:getEEPROM()..c)end}else error("EACCES")end end end end;if a.EFI:getNvram()then function c.nvram(k,e)if k=="type"then return"character device"elseif k=="open"then if e=="r"then local n,q=1,a.EFI:getNvram()return{read=function(l)n=n+l;return q:sub(n-l,n)end}elseif e=="w"then if a.uid~=0 then error("EACCES")end;local p=true;return{write=function(c)if p then a.EFI:setNvram(c)else a.EFI:setNvram(a.EFI:getNvram()..c)end end}elseif e=="a"then if a.uid~=0 then error("EACCES")end;return{write=function(c)a.EFI:setNvram(a.EFI:getNvram()..c)end}else error("EACCES")end end end end;c["disk"]={}a.devfs={}a.devfs.data=c;a.devfs.proxy=b;a.disks["devfs0000"]=b diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/12_procfs.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/12_procfs.kmod deleted file mode 100644 index fedf534..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/12_procfs.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b={}local c={}b.address="procfs0000"b.isvirt=true;b.isReadOnly=function()return true end;b.spaceUsed=function()return 0 end;b.spaceTotal=function()return 0 end;b.makeDirectory=function()error("EACCES")end;b.remove=function()error("EACCES")end;b.setLabel=function()error("EACCES")end;b.getLabel=function()return"procfs"end;b.attributes=function(d)return{size=0,modified=0,created=0}end;local function e(f,g)g=g or{}local h=g.uid or 0;local i=g.gid or 0;local j=g.perms or 0x3F;local k={}table.insert(k,string.char(0x02))for d,l in pairs(f)do local m=d;local n=#m;if n>255 then error("Filename too long (>255 bytes): "..m)end;local o=0x00;local p=""if l and l~=""then o=0x01;p=l end;local q=#p;if q>255 then error("cmeta too long (>255 bytes) for "..m)end;table.insert(k,string.char(n))table.insert(k,m)table.insert(k,string.char(o))table.insert(k,string.char(h%256,math.floor(h/256)%256))table.insert(k,string.char(i%256,math.floor(i/256)%256))table.insert(k,string.char(j%256,math.floor(j/256)%256))table.insert(k,string.char(q))if q>0 then table.insert(k,p)end end;return table.concat(k)end;local function r(s,t)return function(u,v)if u=="type"then return"character device"elseif u=="open"then if v=="r"then return{read=s}elseif v=="w"then return{write=t}end end end end;local function w(x)local y=tostring(x)local z=1;return r(function(A)z=z+A;return y:sub(z-A,z)end,function()error("EACCES")end)end;local function B(C)local D,E,F={},{},{}if C.fd[0]then D["0"]=C.fd[0].path end;for G,H in ipairs(C.fd)do D[tostring(G)]=tostring(H.path)end;for G,H in ipairs(C.siblings)do E[tostring(H.pid)]="/proc/"..tostring(H.pid)end;for G,H in ipairs(C.children)do F[tostring(H.pid)]="/proc/"..tostring(H.pid)end;return{[".meta"]=w(e({cwd=C.cwd,parent="/proc/"..tostring(C.parent.pid)})),uid=w(C.uid),comm=w(C.name),fd={[".meta"]=w(e(D))},siblings={[".meta"]=w(e(E))},children={[".meta"]=w(e(F))}}end;function b:open(d,v)local I=a.vfs.splitPath(d)local J=c;if tonumber(I[1])then local C=a.tasks[tostring(I[1])]local J=B(C)for G=2,#I-1 do local y=J[I[G]]if type(y)~="table"then error("ENFILE")end;J=y end;if type(J[I[#I]])=="function"then return J[I[#I]]("open",v)end elseif tostring(I[1])=="self"then local C=a.currentTask;local J=B(C)for G=2,#I-1 do local y=J[I[G]]if type(y)~="table"then error("ENFILE")end;J=y end;if type(J[I[#I]])=="function"then return J[I[#I]]("open",v)end else for G=1,#I-1 do local y=J[I[G]]if type(y)~="table"then error("ENFILE")end;J=y end;if type(J[I[#I]])=="function"then return J[I[#I]]("open",v)end end;error("ENFILE")end;function b:type(d,v)local I=a.vfs.splitPath(d)local J=c;if#I==0 then return"directory"end;if tonumber(I[1])then local C=a.tasks[I[1]]if#I==1 then return"directory"end;local J=B(C)for G=2,#I-1 do local y=J[I[G]]if type(y)~="table"then error("ENFILE")end;J=y end;if type(J[I[#I]])=="function"then return J[I[#I]]("type",v)end;if type(J[I[#I]])=="table"then return"directory"end elseif tostring(I[1])=="self"then local C=a.currentTask;if#I==1 then return"directory"end;local J=B(C)for G=2,#I-1 do local y=J[I[G]]if type(y)~="table"then error("ENFILE")end;J=y end;if type(J[I[#I]])=="function"then return J[I[#I]]("type",v)end;if type(J[I[#I]])=="table"then return"directory"end else for G=1,#I-1 do local y=J[I[G]]if type(y)~="table"then error("ENFILE")end;J=y end;if type(J[I[#I]])=="function"then return J[I[#I]]("type",v)end;if type(J[I[#I]])=="table"then return"directory"end end;error("ENOENT")end;function b:list(d)local I=a.vfs.splitPath(d)local J=c;if#I==0 then return table.merge(table.keys(c),table.keys(a.tasks),{"self"})end;if tonumber(I[1])then local C=a.tasks[I[1]]local J=B(C)if#I==1 then return table.keys(J)end;for G=2,#I-1 do local y=J[I[G]]if type(y)~="table"then error("ENOENT")end;J=y end;if type(J[I[#I]])=="table"then return table.keys(J[I[#I]])end elseif tostring(I[1])=="self"then local C=a.currentTask;local J=B(C)if#I==1 then return table.keys(J)end;for G=2,#I-1 do local y=J[I[G]]if type(y)~="table"then error("ENOENT")end;J=y end;if type(J[I[#I]])=="table"then return table.keys(J[I[#I]])end else for G=1,#I-1 do local y=J[I[G]]if type(y)~="table"then error("ENOENT")end;J=y end;if type(J[I[#I]])=="table"then return table.keys(J[I[#I]])end end;error("ENOENT")end;function b:fileExists(d)local K=pcall(function()return self:type(d)end)return K end;c.uptime=r(function()return tostring(a.EFI:getUptime())end,function()error("EACCES")end)a.procfs={}a.procfs.data=c;a.procfs.proxy=b;a.disks["procfs0000"]=b diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/12_tmpfs.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/12_tmpfs.kmod deleted file mode 100644 index f60d532..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/12_tmpfs.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b={}local c={}b.address="tmpfs0000"b.isvirt=true;b.isReadOnly=function()return false end;b.spaceUsed=function()return 0 end;b.spaceTotal=function()return 0 end;b.makeDirectory=function(d,e)local f=a.vfs.splitPath(e)local g=c;for h=1,#f do if not g[f[h]]then g[f[h]]={}elseif type(g[f[h]])~="table"then error("ENOTDIR")end;g=g[f[h]]end end;b.remove=function(d,e)local f=a.vfs.splitPath(e)local g=c;for h=1,#f-1 do g=g[f[h]]if not g then error("ENOENT")end end;g[f[#f]]=nil end;b.setLabel=function(d,i)end;b.getLabel=function()return"tmpfs"end;b.attributes=function(d,e)local f=a.vfs.splitPath(e)local g=c;for h=1,#f do g=g[f[h]]if not g then error("ENOENT")end end;return{size=type(g)=="string"and#g or 0,modified=0,created=0}end;function b:open(e,j)local f=a.vfs.splitPath(e)local g=c;for h=1,#f-1 do if not g[f[h]]then if j=="w"then g[f[h]]={}else error("ENOENT")end elseif type(g[f[h]])~="table"then error("ENOTDIR")end;g=g[f[h]]end;local k=f[#f]if j=="r"then if type(g[k])~="string"then error("ENOENT")end;local l=g[k]local m=1;return{read=function(n)n=n or#l;local o=l:sub(m,m+n-1)m=m+#o;return o end,close=function()end}elseif j=="w"then g[k]=""local p={}return{write=function(q)p[#p+1]=q end,close=function()g[k]=table.concat(p)end}elseif j=="a"then if type(g[k])~="string"then g[k]=""end;return{write=function(q)g[k]=g[k]..q end,close=function()end}else error("EACCES")end end;function b:type(e)local f=a.vfs.splitPath(e)local g=c;if#f==0 then return"directory"end;for h=1,#f do g=g[f[h]]if not g then return false end end;if type(g)=="table"then return"directory"end;if type(g)=="string"then return"file"end end;function b:list(e)local f=a.vfs.splitPath(e)local g=c;for h=1,#f do g=g[f[h]]if not g then error("ENOENT")end end;if type(g)~="table"then error("ENOTDIR")end;local r={}for s,d in pairs(g)do table.insert(r,s)end;return r end;function b:fileExists(e)local t=self:type(e)return t=="file"or t=="directory"end;a.disks["tmpfs0000"]=b diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/13_loopdev.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/13_loopdev.kmod deleted file mode 100644 index 38573af..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/13_loopdev.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b=nil;local function c()if b==nil then local d,e=pcall(require,"store.deflate")b=d and e or false end;return b or nil end;local function f(g)g=math.floor(g)%4294967296;return string.char(g%256,math.floor(g/256)%256,math.floor(g/65536)%256,math.floor(g/16777216)%256)end;local function h(i,j)local k,l,m,n=i:byte(j,j+3)return(k or 0)+(l or 0)*256+(m or 0)*65536+(n or 0)*16777216 end;local o="BHFS"local p="\001"local q=1;local r="\001"local s="\002"local t="\003"local u="\255"local v={}do local k="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"for j=1,#k do v[k:sub(j,j)]=j-1 end end;local function w(i)i=i:gsub("[^A-Za-z0-9+/=]","")local x,j={},1;while j<=#i do local y=v[i:sub(j,j)]or 0;local z=v[i:sub(j+1,j+1)]or 0;local A=v[i:sub(j+2,j+2)]or 0;local B=v[i:sub(j+3,j+3)]or 0;local g=y*262144+z*4096+A*64+B;x[#x+1]=string.char(math.floor(g/65536)%256)if i:sub(j+2,j+2)~="="then x[#x+1]=string.char(math.floor(g/256)%256)end;if i:sub(j+3,j+3)~="="then x[#x+1]=string.char(g%256)end;j=j+4 end;return table.concat(x)end;local C={}local D=0;local function E(F,G)local H={address=F,isvirt=false}H.isReadOnly=function()return false end;H.spaceUsed=function()return 0 end;H.spaceTotal=function()return 0 end;H.setLabel=function()end;H.getLabel=function()return F end;local function I()local J,K="/","$"for L,M in pairs(a.vfs.mounts)do if G==M or M=="/"and G:sub(1,1)=="/"or G:sub(1,#M+1)==M.."/"then if#M>#J then J=M;K=L end end end;return a.vfs.disks[K],G:sub(#J+1)end;local function N(O)local P,Q=I()local l=(Q==""or Q=="/")and""or Q:gsub("^/+","")local R=O:gsub("^/+","")local m=(l==""and"/"..R or"/"..l.."/"..R):gsub("//+","/")local S=m:sub(2)if S==""then S="/"end;return P,S end;function H:open(O,T)local U,S=N(O)return U:open(S,T)end;function H:type(O)local U,S=N(O)return U:type(S)end;function H:list(O)local U,S=N(O)return U:list(S)end;function H:fileExists(O)local U,S=N(O)return U:fileExists(S)end;function H:attributes(O)local U,S=N(O)return U:attributes(S)end;function H:makeDirectory(O)local U,S=N(O)return U:makeDirectory(S)end;function H:remove(O)local U,S=N(O)return U:remove(S)end;return H end;local function V(F,W)local X={kind="dir",children={}}local function Y(O,Z)local _={}for R in O:gmatch("[^/]+")do _[#_+1]=R end;local a0=X;for j=1,#_ do local a1=_[j]if not a0.children then if not Z then return nil end;a0.children={}end;if not a0.children[a1]then if not Z then return nil end;a0.children[a1]={kind="dir",children={}}end;a0=a0.children[a1]end;return a0 end;local function a2(O)local a3=O:match("^(.*)/[^/]+$")or""if a3~=""then local g=Y(a3,true)if not g.children then g.children={}end end end;if W:sub(1,4)==o then local a4=9;while a4<=#W do local a5=W:sub(a4,a4)a4=a4+1;if a5==u then break end;local a6=h(W,a4)a4=a4+4;local a7=h(W,a4)a4=a4+4;local a8=h(W,a4)a4=a4+4;local O=W:sub(a4,a4+a6-1)a4=a4+a6;local a9=W:sub(a4,a4+a8-1)a4=a4+a8;local aa=a9;if a80 and w(ae)or""local g=Y(R,true)g.kind="file"g.data=aa;g.size=#aa;g.children=nil end elseif ac:sub(1,5)=="LINK "then local R,af=ac:sub(6):match("^(%S+)%s+(.+)$")if R then a2(R)local g=Y(R,true)g.kind="link"g.target=af;g.children=nil end end end end;local H={address=F,isvirt=false}H.isReadOnly=function()return false end;H.spaceTotal=function()return 1024*1024*64 end;H.spaceUsed=function()local ag=0;local function ah(g)if g.kind=="file"then ag=ag+(g.size or 0)elseif g.kind=="dir"then for ai,m in pairs(g.children or{})do ah(m)end end end;ah(X)return ag end;H.setLabel=function()end;H.getLabel=function()return F end;local function aj(O)return O:gsub("^/+",""):gsub("/+$","")end;function H:type(O)local R=aj(O)if R==""then return"directory"end;local g=Y(R)if not g then return nil end;if g.kind=="dir"then return"directory"end;return"file"end;function H:fileExists(O)local R=aj(O)if R==""then return true end;return Y(R)~=nil end;function H:list(O)local R=aj(O)local a0=R==""and X or Y(R)if not a0 or a0.kind~="dir"then return{}end;local ak={}for a1 in pairs(a0.children or{})do ak[#ak+1]=a1 end;return ak end;function H:attributes(O)local R=aj(O)local a0=R==""and X or Y(R)if not a0 then return nil end;return{size=a0.kind=="file"and(a0.size or 0)or 0,isDir=a0.kind=="dir",isReadOnly=false,created=0,modified=0}end;function H:open(O,T)local R=aj(O)local a0=Y(R)if T=="r"then if not a0 or a0.kind~="file"then error("ENOENT: "..O)end;local aa,a4=a0.data or"",1;return{read=function(g)if a4>#aa then return nil end;local al=aa:sub(a4,a4+(g or 1)-1)a4=a4+#al;return al end,readAll=function()local am=aa:sub(a4)a4=#aa+1;return am end,readLine=function()if a4>#aa then return nil end;local an=aa:find("\n",a4,true)local ac;if an then ac=aa:sub(a4,an-1)a4=an+1 else ac=aa:sub(a4)a4=#aa+1 end;return ac end,seek=function(ah,ao)ao=ao or 0;if ah=="set"then a4=ao+1 elseif ah=="cur"then a4=a4+ao elseif ah=="end"then a4=#aa+1+ao end;return a4-1 end,close=function()end}elseif T=="w"or T=="a"then local ap=T=="a"and a0 and a0.kind=="file"and{a0.data or""}or{}local aq=false;local function ar()if aq then return end;aq=true;local aa=table.concat(ap)if not a0 then a2(R)a0=Y(R,true)end;a0.kind="file"a0.data=aa;a0.size=#aa;a0.children=nil end;return{write=function(i)ap[#ap+1]=tostring(i)end,writeLine=function(i)ap[#ap+1]=tostring(i).."\n"end,flush=function()end,close=ar}else error("EINVAL: unknown mode: "..tostring(T))end end;function H:makeDirectory(O)local R=aj(O)if R==""then return end;a2(R)local g=Y(R,true)g.kind="dir"g.children=g.children or{}g.data=nil;g.size=nil end;function H:remove(O)local R=aj(O)if R==""then error("EBUSY: cannot remove root")end;local a3=R:match("^(.*)/[^/]+$")or""local a1=R:match("([^/]+)$")local as=a3==""and X or Y(a3)if as and as.children then as.children[a1]=nil end end;H._root=X;return H end;local function at(au)local ab=c()local av=ab~=nil;local aw=av and q or 0;local _={o,p,string.char(aw),"\0\0"}au=au:gsub("/$","")local ax=64;local function ay(az)local aA=a.vfs.type(az)if aA=="directory"then if az~=au then local aB=az:sub(#au+1)_[#_+1]=s;_[#_+1]=f(#aB)_[#_+1]=f(0)_[#_+1]=f(0)_[#_+1]=aB end;local d,aC=pcall(a.vfs.listdir,az)if d and aC then table.sort(aC)for ai,a1 in ipairs(aC)do ay(az:gsub("/$","").."/"..a1)end end elseif aA=="file"then local aB=az:sub(#au+1)local d,aD=pcall(a.vfs.open,az,"r")if d then local aE=""local aF,aG=pcall(a.vfs.read,aD,1024*1024)if aF then aE=aG or""end;pcall(a.vfs.close,aD)local aH=aE;if av and#aE>=ax then local aI=ab.compress(aE)if aI and#aI<#aE then aH=aI end end;_[#_+1]=r;_[#_+1]=f(#aB)_[#_+1]=f(#aE)_[#_+1]=f(#aH)_[#_+1]=aB;_[#_+1]=aH end end end;ay(au)_[#_+1]=u;return table.concat(_)end;a.syscalls["losetup"]=function(aJ,aK)if not aJ then error("EINVAL")end;local aL=a.currentTask;local aM=aL and(aL.euid or aL.uid)or a.uid;if aM~=0 then error("EPERM")end;aJ=aJ:gsub("/$","")local F="loop"..tostring(D)D=D+1;local aA=a.vfs.type(aJ)local H,T;if not aK and aA=="directory"then H=E(F,aJ)T="bind"elseif aA=="file"or aK then if aA~="file"then error("ENOENT: not a file: "..aJ)end;local aN;local d,aD=pcall(a.vfs.open,aJ,"rb")if d then local aF,aa=pcall(a.vfs.read,aD,1024*1024*16)pcall(a.vfs.close,aD)if aF and aa then aN=aa end end;if not aN then local aF,aO=pcall(a.vfs.open,aJ,"r")if not aF then error("EIO: cannot open image: "..aJ)end;local aP,aa=pcall(a.vfs.read,aO,1024*1024*16)pcall(a.vfs.close,aO)if not aP or not aa then error("EIO: cannot read image: "..aJ)end;aN=aa end;H=V(F,aN)T="image"else error("EINVAL: path must be a directory or .hfs image file")end;a.vfs.disks[F]=H;C[F]={path=aJ,disk=H,mode=T}a.log("losetup: attached "..F.." ("..T..") -> "..aJ,"INFO")return F end;a.syscalls["lodetach"]=function(F)local aL=a.currentTask;local aM=aL and(aL.euid or aL.uid)or a.uid;if aM~=0 then error("EPERM")end;if not C[F]then error("ENXIO")end;for K in pairs(a.vfs.mounts)do if K==F then error("EBUSY: loop device is still mounted")end end;a.vfs.disks[F]=nil;C[F]=nil;a.log("lodetach: detached "..F,"INFO")end;a.syscalls["lolist"]=function()local aQ={}for F,aR in pairs(C)do aQ[F]={path=aR.path,mode=aR.mode}end;return aQ end;a.syscalls["loimgcreate"]=function(au)local aL=a.currentTask;local aM=aL and(aL.euid or aL.uid)or a.uid;if aM~=0 then error("EPERM")end;if not au then error("EINVAL")end;if a.vfs.type(au)~="directory"then error("ENOTDIR: "..au)end;return at(au)end;a.syscalls["loimgwrite"]=function(aS,aT)local aL=a.currentTask;local aM=aL and(aL.euid or aL.uid)or a.uid;if aM~=0 then error("EPERM")end;if not aS or not aT then error("EINVAL")end;local d,aD=pcall(a.vfs.open,aT,"wb")if not d then d,aD=pcall(a.vfs.open,aT,"w")if not d then error("EIO: cannot write: "..tostring(aT))end end;local aF,aU=pcall(a.vfs.write,aD,aS)pcall(a.vfs.close,aD)if not aF then error("EIO: write failed: "..tostring(aU))end end;a.log("Loop device driver loaded (bind + BHFS binary image + legacy HFS compat)") diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/19_fstab.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/19_fstab.kmod deleted file mode 100644 index 30170a8..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/19_fstab.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local function b(c)local d,e=1,#c;while d<=e and(c:sub(d,d)==" "or c:sub(d,d)=="\t")do d=d+1 end;while e>=d and(c:sub(e,e)==" "or c:sub(e,e)=="\t"or c:sub(e,e)=="\n"or c:sub(e,e)=="\r")do e=e-1 end;if d>e then return""end;return c:sub(d,e)end;for f,g in ipairs(string.split(a.fstab,"\n"))do g=b(g)if g~=""and g:sub(1,1)=="U"then local h;for i=3,#g do if g:sub(i,i)==";"then h=i;break end end;if not h or h==3 then a.log("Invalid fstab line: "..g.." ... Skipping.","WARN",0xFF8800)else local j=g:sub(3,h-1)local k=b(g:sub(h+1))a.log("Mounted "..j.." to "..k)if j~="$"then a.vfs.mount(k,j)end end end end diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/20_signals.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/20_signals.kmod deleted file mode 100644 index 88b1567..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/20_signals.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b={}a.signal=b;function b.sigsend(c,d)if d<0 or d>256 then error("EINVAL")end;local e=a.tasks[tostring(c)]if not e then error("ENOENT")end;if not e.sigq then return end;e.sigq[#e.sigq+1]=d end;function b.sigcatch(f)local e=a.currentTask;e.sigh=f;if not e.sigq then e.sigq={}end;local g={error="",active=true}if e.sigd then e.sigd.active=false end;e.sigd=g;return g end;function b.sigignore()local e=a.currentTask;e.sigh=nil;e.sigq=nil;if e.sigd then e.sigd.active=false end;e.sigd=nil end;local h=a.syscalls;h["sigsend"]=b.sigsend;h["sigcatch"]=b.sigcatch;h["sigignore"]=b.sigignore diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/20_socket.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/20_socket.kmod deleted file mode 100644 index 74ab5ee..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/20_socket.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b={}b.handlers={}a.socket=b;function b.registerProtocal(c,d)b.handlers[c]=d end;function b.socket()local e=a.vfs.P;local f=a.newFifo()local g=false;a.vfs.newfd({handle={read=function()if g then error("ECCON")end;return f.read()end,write=function()if g then error("ECCON")end;return f.write()end,close=function()g=true end},type="socket",refcount=1,meta={owner=a.currentTask.uid,group=a.currentTask.uid,etype=2,perms=e.OWNER_R+e.OWNER_W+e.GROUP_R+e.GROUP_W},isvirt=true})end;function b.connect(h,i)end;function b.listen(h,j)end;a.log("Loaded socket module") diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/21_unixsockets.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/21_unixsockets.kmod deleted file mode 100644 index a8d1eba..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/21_unixsockets.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...a.unixSockets={} diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/30_userspace.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/30_userspace.kmod deleted file mode 100644 index 8b69866..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/30_userspace.kmod +++ /dev/null @@ -1 +0,0 @@ -local a={...}local b=a[1]b._G=_G;local function c(d)return setmetatable({},{__index=function(e,f)local g=d[f]if type(g)=="table"then return c(g)end;return g end,__newindex=function(h,i,j)if b.config.allowGlobalOverwrites or b.allowGlobalOverwrites then rawset(d,i,j)return end;error("Attempt to modify global variable '"..i.."'",2)end,__pairs=function(self)local function k(e,f)local l,g=next(d,f)if type(g)=="table"then g=c(g)end;return l,g end;return k,self,nil end,__ipairs=function()local m=0;return function()m=m+1;local g=d[m]if g==nil then return end;if type(g)=="table"then g=c(g)end;return m,g end end,__len=function()return#d end,__metatable=false})end;local n=load;b._U=c(b._G)b._U._G=b._U;b._U.load=function(o,p,q,r)return n(o,p,q,r or b._U)end;function b.freshUserEnv()local s={}s.syscall=_makeSyscallProxy()local t=setmetatable(s,{__index=b._U,__newindex=function(e,i,j)rawset(s,i,j)end,__metatable=false})s._G=t;s.load=function(o,p,q,r)return n(o,p,q,r or t)end;return t end diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/40_auth.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/40_auth.kmod deleted file mode 100644 index c05bf52..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/40_auth.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b={}a.auth=b;local function c(d)local e=a.vfs.open(d,"r")if not e then error("Failed to open file: "..d)end;local f=a.vfs.read(e,1024000)a.vfs.close(e)return f end;local function g(d,f)local e=a.vfs.open(d,"w")if not e then error("Failed to open file for writing: "..d)end;a.vfs.write(e,f)a.vfs.close(e)end;local h;do local i=2^32;local function j(k)return k%i end;local function l(k)k=j(k)local m={}for n=0,31 do local o=k%2;m[n]=o;k=(k-o)/2 end;return m end;local function p(m)local k,q=0,1;for n=0,31 do if m[n]==1 then k=k+q end;q=q*2 end;return j(k)end;local function r(...)local s={...}if#s==0 then return 0 end;local t=l(s[1])for n=2,#s do local o=l(s[n])for u=0,31 do t[u]=(t[u]==1 or o[u]==1)and 1 or 0 end end;return p(t)end;local function v(...)local s={...}if#s==0 then return 0 end;local t=l(s[1])for n=2,#s do local o=l(s[n])for u=0,31 do t[u]=t[u]~=o[u]and 1 or 0 end end;return p(t)end;local function w(k,x)return j(j(k)*2^x)end;local function y(k,x)return math.floor(j(k)/2^x)end;local function z(k,x)return r(y(k,x),w(k,32-x))end;local A={0x6A09E667,0xBB67AE85,0x3C6EF372,0xA54FF53A,0x510E527F,0x9B05688C,0x1F83D9AB,0x5BE0CD19}local B={{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},{14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3},{11,8,12,0,5,2,15,13,10,14,3,6,7,1,9,4},{7,9,3,1,13,12,11,14,2,6,5,10,4,0,15,8},{9,0,5,7,2,4,10,15,14,1,11,12,6,8,3,13},{2,12,6,10,0,11,8,3,4,13,7,5,15,14,1,9},{12,5,1,15,14,13,4,10,0,7,6,3,9,2,8,11},{13,11,7,14,12,1,3,9,5,0,15,4,8,6,2,10},{6,15,14,9,11,3,0,8,12,2,13,7,1,4,10,5},{10,2,8,4,7,6,1,5,15,11,9,14,3,12,13,0}}local function C(D,E,o,F,G,k,H)D[E]=(D[E]+D[o]+k)%i;D[G]=z(v(D[G],D[E]),16)D[F]=(D[F]+D[G])%i;D[o]=z(v(D[o],D[F]),12)D[E]=(D[E]+D[o]+H)%i;D[G]=z(v(D[G],D[E]),8)D[F]=(D[F]+D[G])%i;D[o]=z(v(D[o],D[F]),7)end;local function I(J,K,m,L)local D={}for n=1,8 do D[n]=J[n]end;for n=1,8 do D[n+8]=A[n]end;D[13]=v(D[13],m)if L then D[15]=v(D[15],0xFFFFFFFF)end;local M={}for n=0,15 do local q=n*4+1;M[n]=(K:byte(q)or 0)+(K:byte(q+1)or 0)*0x100+(K:byte(q+2)or 0)*0x10000+(K:byte(q+3)or 0)*0x1000000 end;for N=1,10 do local O=B[N]C(D,1,5,9,13,M[O[1]],M[O[2]])C(D,2,6,10,14,M[O[3]],M[O[4]])C(D,3,7,11,15,M[O[5]],M[O[6]])C(D,4,8,12,16,M[O[7]],M[O[8]])C(D,1,6,11,16,M[O[9]],M[O[10]])C(D,2,7,12,13,M[O[11]],M[O[12]])C(D,3,8,9,14,M[O[13]],M[O[14]])C(D,4,5,10,15,M[O[15]],M[O[16]])end;for n=1,8 do J[n]=v(J[n],D[n],D[n+8])end end;function h(P,Q)Q=Q or""local J={}for n=1,8 do J[n]=A[n]end;local R=32;J[1]=v(J[1],0x01010000+w(#Q,8)+R)local m=0;if#Q>0 then local K=Q..string.rep("\0",64-#Q)m=#Q;I(J,K,m,false)end;for n=1,#P,64 do local K=P:sub(n,n+63)if#K<64 then K=K..string.rep("\0",64-#K)end;m=m+math.min(64,#P-n+1)I(J,K,m,n+64>#P)end;local S=""for n=1,8 do S=S..string.format("%08x",J[n])end;return S end end;if not h then error("Failed to load blake2s")end;if not a.vfs.exists("/etc/pam.d/secret")then a.log("PAM SECRET REGENERATING PLEASE USE ROOT","WARN",0xFF8800)local Q=""for n=1,256 do Q=Q..string.char(math.random(0,255))end;local T=a.vfs.open("/etc/pam.d/secret","w")a.vfs.write(T,Q)a.vfs.close(T)end;local U=c("/etc/pam.d/secret")local function V()return toHex(math.random(0,2^32))end;local function W(X,Y)local Q=U..Y;return h(X,Q)end;local Z=c("/etc/passwd")local _=c("/etc/shadow")local a0=string.split(Z,"\n")local a1=string.split(_,"\n")local a2,a3={},{}for a4,D in ipairs(a0)do local a5=string.split(D,":")if a5[1]and a5[1]~=""then a2[#a2+1]=a5 end end;for a4,D in ipairs(a1)do local a5=string.split(D,":")if a5[1]and a5[1]~=""then a3[#a3+1]=a5 end end;for a4,D in ipairs(a2)do local a6=tonumber(D[1])if a6 then a.users[a6]=D[3]end end;a.passwd=a2;local function a7()local a8={}for a4,D in ipairs(a2)do a8[#a8+1]=table.concat(D,":")end;g("/etc/passwd",table.concat(a8,"\n"))end;local function a9()local a8={}for a4,D in ipairs(a3)do a8[#a8+1]=table.concat(D,":")end;g("/etc/shadow",table.concat(a8,"\n"))end;local function aa(a6)for a4,D in ipairs(a2)do if tonumber(D[1])==a6 then return D end end;return nil end;local function ab(a6)for a4,D in ipairs(a3)do if tonumber(D[1])==a6 then return D end end;return nil end;local function ac(ad)for a4,D in ipairs(a2)do if D[3]==ad then return D end end;return nil end;local function ae()local af=999;for a4,D in ipairs(a2)do local a6=tonumber(D[1])if a6 and a6>=1000 and a6>af then af=a6 end end;return af+1 end;function b.login(a6,X)if type(a6)~="number"or type(X)~="string"then return nil,"Authentication failure"end;local ag=aa(a6)if not ag then W(X,"aaaaaaaaaaaaaaaa")return nil,"Authentication failure"end;local ah=ab(a6)if not ah then W(X,"aaaaaaaaaaaaaaaa")return nil,"Authentication failure"end;local Y=ah[2]local ai=ah[3]local aj=W(X,Y)if aj~=ai then return nil,"Authentication failure"end;a.currentUID=a6;local ak=a.currentTask;if ak then ak.uid=a6;ak.euid=a6;ak.gid=tonumber(ag[2])or a6;ak.egid=tonumber(ag[2])or a6 end;a.log("AUTH: login uid="..tostring(a6).." ("..aa(a6)[3]..")")return true end;function b.setPassword(a6,al)a6=tonumber(a6)if not a6 then return nil,"Invalid uid"end;local am=a.currentProcess and a.currentProcess.euid or a.currentUID or 0;if am~=0 and am~=a6 then return nil,"Permission denied"end;if type(al)~="string"or#al==0 then return nil,"Password may not be empty"end;if#al<6 then return nil,"Password is too short (minimum 6 characters)"end;local Y=V()local an=W(al,Y)local ah=ab(a6)if ah then ah[2]=Y;ah[3]=an else a3[#a3+1]={tostring(a6),Y,an}end;a9()a.log("AUTH: password changed for uid="..tostring(a6))return true end;function b.setUsername(a6,ao)a6=tonumber(a6)if not a6 then return nil,"Invalid uid"end;local am=a.currentProcess and a.currentProcess.euid or a.currentUID or 0;if am~=0 then return nil,"Permission denied (root only)"end;if type(ao)~="string"or#ao==0 then return nil,"Invalid username"end;if not ao:match("^[a-z_][a-z0-9_%-]*$")or#ao>32 then return nil,"Invalid username format"end;if ac(ao)then return nil,"Username already taken"end;local ag=aa(a6)if not ag then return nil,"No such user"end;local ap=ag[3]ag[3]=ao;a.users[a6]=ao;a7()a.log("AUTH: uid="..tostring(a6).." renamed '"..ap.."' → '"..ao.."'")return true end;function b.newUser(ad,X,aq,ar,as)local am=a.currentProcess and a.currentProcess.euid or a.currentUID or 0;if am~=0 then return nil,"Permission denied (root only)"end;if type(ad)~="string"or#ad==0 then return nil,"Invalid username"end;if not ad:match("^[a-z_][a-z0-9_%-]*$")or#ad>32 then return nil,"Invalid username format"end;if ac(ad)then return nil,"Username already exists"end;if type(X)~="string"or#X<6 then return nil,"Password is too short (minimum 6 characters)"end;local a6=ae()aq=tonumber(aq)or a6;ar=ar or"/home/"..ad;as=as or"/bin/hysh"a2[#a2+1]={tostring(a6),tostring(aq),ad,ar,as}a.users[a6]=ad;local Y=V()local an=W(X,Y)a3[#a3+1]={tostring(a6),Y,an}a7()a9()if a.vfs.mkdir and not a.vfs.exists(ar)then a.vfs.mkdir(ar)pcall(a.vfs.chown,ar,a6,a6)end;a.log("AUTH: new user '"..ad.."' uid="..tostring(a6))return a6 end;function b.whoami()local a6=a.currentProcess and a.currentProcess.euid or a.currentUID;if not a6 then return nil,"Not logged in"end;return a.users[a6]or"uid="..tostring(a6)end;function b.getUID(ad)local ag=ac(ad)if ag then return tonumber(ag[1])end;return nil end;function b.getPasswd(a6)a6=tonumber(a6)local ag=aa(a6)if not ag then return nil end;return{uid=tonumber(ag[1]),gid=tonumber(ag[2]),username=ag[3],homedir=ag[4],shell=ag[5]}end;function b.deleteUser(a6)a6=tonumber(a6)if not a6 then return nil,"Invalid uid"end;local am=a.uid or 0;if am~=0 then return nil,"Permission denied (root only)"end;if a6==0 then return nil,"Cannot delete root"end;local ag=aa(a6)if not ag then return nil,"No such user"end;local ad=ag[3]for n,D in ipairs(a2)do if tonumber(D[1])==a6 then table.remove(a2,n)break end end;for n,D in ipairs(a3)do if tonumber(D[1])==a6 then table.remove(a3,n)break end end;a.users[a6]=nil;a7()a9()a.log("AUTH: deleted user '"..ad.."' uid="..tostring(a6))return true end;function b.lockUser(a6)a6=tonumber(a6)if not a6 then return nil,"Invalid uid"end;local am=a.uid or 0;if am~=0 then return nil,"Permission denied (root only)"end;if a6==0 then return nil,"Cannot lock root"end;local ah=ab(a6)if not ah then return nil,"No shadow entry for uid"end;if ah[3]:sub(1,1)~="!"then ah[3]="!"..ah[3]end;a9()a.log("AUTH: locked uid="..tostring(a6))return true end;function b.unlockUser(a6)a6=tonumber(a6)if not a6 then return nil,"Invalid uid"end;local am=a.uid or 0;if am~=0 then return nil,"Permission denied (root only)"end;local ah=ab(a6)if not ah then return nil,"No shadow entry for uid"end;if ah[3]:sub(1,1)=="!"then ah[3]=ah[3]:sub(2)end;a9()a.log("AUTH: unlocked uid="..tostring(a6))return true end;function b.listUsers()local at={}for a4,D in ipairs(a2)do local a6=tonumber(D[1])local ah=ab(a6)local au=ah and ah[3]:sub(1,1)=="!"at[#at+1]={uid=a6,gid=tonumber(D[2]),username=D[3],homedir=D[4],shell=D[5],locked=au or false}end;return at end;function b.setShell(a6,as)a6=tonumber(a6)if not a6 then return nil,"Invalid uid"end;local am=a.uid or 0;if am~=0 and am~=a6 then return nil,"Permission denied"end;if type(as)~="string"or#as==0 then return nil,"Invalid shell"end;local ag=aa(a6)if not ag then return nil,"No such user"end;ag[5]=as;a7()a.log("AUTH: uid="..tostring(a6).." shell -> "..as)return true end;function b.setHomedir(a6,ar)a6=tonumber(a6)if not a6 then return nil,"Invalid uid"end;local am=a.uid or 0;if am~=0 then return nil,"Permission denied (root only)"end;if type(ar)~="string"or#ar==0 then return nil,"Invalid homedir"end;local ag=aa(a6)if not ag then return nil,"No such user"end;ag[4]=ar;a7()a.log("AUTH: uid="..tostring(a6).." homedir -> "..ar)return true end;function b.setGID(a6,aq)a6=tonumber(a6)aq=tonumber(aq)if not a6 or not aq then return nil,"Invalid uid or gid"end;local am=a.uid or 0;if am~=0 then return nil,"Permission denied (root only)"end;local ag=aa(a6)if not ag then return nil,"No such user"end;ag[2]=tostring(aq)a7()a.log("AUTH: uid="..tostring(a6).." gid -> "..tostring(aq))return true end;function b.elevate(av,X)if type(av)~="string"or type(X)~="string"then return nil,"Authentication failure"end;local ag=ac(av)if not ag then W(X,"aaaaaaaaaaaaaaaa")return nil,"Authentication failure"end;local a6=tonumber(ag[1])local ah=ab(a6)if not ah then W(X,"aaaaaaaaaaaaaaaa")return nil,"Authentication failure"end;local aj=W(X,ah[2])if aj~=ah[3]then return nil,"Authentication failure"end;local aw=a.currentTask;local ax=aw.uid;aw.uid=0;aw.euid=0;aw.gid=0;aw.egid=0;a.uid=0;a.log("AUTH: elevate uid="..tostring(ax).." -> 0 (via "..av..")")return true,a6 end;if a.syscalls then a.syscalls["login"]=b.login;a.syscalls["setpassword"]=b.setPassword;a.syscalls["setusername"]=b.setUsername;a.syscalls["newuser"]=b.newUser;a.syscalls["whoami"]=b.whoami;a.syscalls["getuidbyname"]=b.getUID;a.syscalls["getpasswd"]=b.getPasswd;a.syscalls["elevate"]=b.elevate;a.syscalls["deleteuser"]=b.deleteUser;a.syscalls["lockuser"]=b.lockUser;a.syscalls["unlockuser"]=b.unlockUser;a.syscalls["listusers"]=b.listUsers;a.syscalls["setshell"]=b.setShell;a.syscalls["sethomedir"]=b.setHomedir;a.syscalls["setgid"]=b.setGID end diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/45_hypervisor.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/45_hypervisor.kmod deleted file mode 100644 index f5338e3..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/45_hypervisor.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b={}local c={}local d=2;a.exitMain=false;local e=coroutine.resumeWithTimeout;local function f(g,h)return math.floor(g/2^h)%2==1 end;local function i(j)a.vfs.access(j,"rx")local k=a.vfs.open(j,"r")local l=a.vfs.read(k,1024*1024*4)a.vfs.close(k)local m=a.freshUserEnv()local n,o=load(l,"@"..j,"t",m)if not n then error("ENOEXEC: "..tostring(o))end;local p=a.vfs.lstat(j)local q=f(p.perms,6)local r=a.currentTask and a.currentTask.uid or a.uid;local s=q and p.owner or r;return n,s,q end;local function t(n,u,v,w,x,y,z)local A=d;d=d+1;b[tostring(A)]={coro=coroutine.create(function()local B,o=xpcall(n,debug.traceback,table.unpack(w or{}))if a.config.logTaskExit then if not B then a.log("Task "..tostring(A).." exited with err: "..tostring(o),"ERROR",0xFF0000)elseif o then a.log("Task "..tostring(A).." exited with code: "..tostring(o),"DBUG",0x00FFFF)else a.log("Task "..tostring(A).." exited without code","DBUG",0x00FFFF)end end;if type(o)=="number"then b[tostring(A)].exit=o end;if b[tostring(A)].fd then for k,C in pairs(b[tostring(A)].fd)do pcall(a.vfs.close,k)end end;b[tostring(A)].status="Z"end),name=u or"task"..tostring(A),envars=v or(a.currentTask and a.currentTask.envars or{}),args=w or{},status="R",pid=A,tgid=x or(a.currentTask and a.currentTask.tgid or A),uid=y,euid=z,gid=a.currentTask and a.currentTask.gid or 0,groups=a.currentTask and a.currentTask.groups or{},fd={},sleep=0,ivs=0,vs=0,children={},parent=a.currentTask or a.kernelTask,siblings=a.currentTask and a.currentTask.children or a.kernelTask.children,syscallReturn={},cwd=a.currentTask and a.currentTask.cwd or"/",timeSlice=0,lastTime=0,totalTime=0,numRuns=0}table.insert(a.currentTask and a.currentTask.children or a.kernelTask.children,b[tostring(A)])return A end;function c.spawn(n,u,v,w,x)local D=a.currentTask;local y=D and D.uid or a.uid;local z=D and D.euid or y;return t(n,u,v,w,x,y,z)end;function c.execspawn(j,u,v,w,x)local n,s,E=i(j,a._U)local D=a.currentTask;local y=D and D.uid or a.uid;if E then a.log("execspawn: suid exec '"..j.."' caller_uid="..tostring(y).." -> euid="..tostring(s))end;return t(n,u or j,v,w,x,y,s)end;function c.exec(j,w,v)local F=a.currentTask;local n,s,C=i(j,a._U)if F.fd then for k,C in pairs(F.fd)do if k>2 then pcall(a.vfs.close,k)end end end;F.euid=s;F.args=w or{}F.envars=v or F.envars;F.name=j;F.coro=coroutine.create(function()local B,o=xpcall(n,debug.traceback,table.unpack(F.args))if a.config.logTaskExit then if not B then a.log("Task "..tostring(F.pid).." exec '"..j.."' err: "..tostring(o),"ERROR",0xFF0000)else a.log("Task "..tostring(F.pid).." exec '"..j.."' exited: "..tostring(o),"DBUG",0x00FFFF)end end;if type(o)=="number"then b[tostring(F.pid)].exit=o end;if b[tostring(F.pid)].fd then for k,C in pairs(b[tostring(F.pid)].fd)do pcall(a.vfs.close,k)end end;b[tostring(F.pid)].status="Z"end)F.syscallReturn={}coroutine.yield()end;function c.sleep(G)a.currentTask.status="S"a.currentTask.sleep=a.EFI:getEpochMs()+G*1000 end;function c.getTask(H)local F=b[tostring(H)]if not F then return nil end;local I,J={},{}for K,L in ipairs(F.children)do I[K]=L.pid end;for K,L in ipairs(F.siblings)do J[K]=L.pid end;return{name=F.name,status=F.status,pid=F.pid,tgid=F.tgid,username=a.users[F.uid],uid=F.uid,euid=F.euid,exit=F.exit,sleep=F.sleep,ivs=F.ivs,vs=F.vs,children=I,siblings=J,parent=F.parent.pid,cwd=F.cwd,term=F.term}end;function c.collect(H)local I={}for C,L in ipairs(a.currentTask.children)do I[#I+1]=L.pid end;local F=b[tostring(H)]if not F then return false,"Task does not exist"elseif not isEqualToAny(F.pid,table.unpack(I))then return false,"You do not own this task"elseif F.status~="Z"then return false,"Task must exit to collect status"else F.reapTime=0;return true,F.exit end end;function c.kill(H)local F=b[tostring(H)]if not F then return false,"Task does not exist"elseif F.status=="Z"then return false,"Task is already dead"end;local D=a.currentTask;local M=D and(D.euid or D.uid)or a.uid;if M~=0 and F.uid~=(D and D.uid or a.uid)then return false,"EPERM"end;F.status="Z"return true end;function c.stop(H)local F=b[tostring(H)]if not F then return false,"Task does not exist"elseif F.status~="R"then return false,"Cannot stop non-running task"else F.status="T"return true end end;function c.continue(H)local F=b[tostring(H)]if not F then return false,"Task does not exist"elseif F.status~="T"then return false,"Task is not stopped"else F.status="R"return true end end;function c.getpid()return a.currentTask.pid end;function c.getppid()return a.currentTask.parent.pid end;function c.getTasks()local N={}for C,L in pairs(b)do N[#N+1]=L.pid end;return N end;function c.getEnviron(O)return a.currentTask.envars[O]end;function c.setEnviron(O,P)a.currentTask.envars[O]=P end;function c.exit(Q)local F=a.currentTask;if a.config.logTaskExit then if Q then a.log("Task "..tostring(F.pid).." exited with code: "..tostring(Q),"DBUG",0x00FFFF)else a.log("Task "..tostring(F.pid).." exited without code","DBUG",0x00FFFF)end end;b[tostring(F.pid)].status="Z"if type(Q)=="number"then b[tostring(F.pid)].exit=Q end end;function c.setuid(R)local F=a.currentTask;if F.euid~=0 and F.uid~=R then error("EPERM")end;F.uid=R;F.euid=R;a.uid=R end;function c.geteuid()return a.currentTask.euid end;function c.getuid()return a.currentTask.uid end;local function S()for H,F in pairs(b)do if F.status=="Z"and not F.reapTime then F.coro=nil;F.ivs=nil;F.vs=nil;F.args=nil;F.envars=nil;F.cwd=nil;F.numRuns=nil;F.totalTime=nil;F.lastTime=nil;F.timeSlice=nil;F.syscallReturn=nil;F.sleep=nil;F.fd=nil;F.reapTime=a.EFI:getEpochMs()+30000 elseif F.reapTime and a.EFI:getEpochMs()>F.reapTime and F.status=="Z"then for C,T in ipairs(F.children)do T.parent=b["1"]T.siblings=b["1"].children;table.insert(b["1"].children,T)end;for K,U in ipairs(F.siblings)do if U.pid==F.pid then table.remove(F.siblings,K)break end end;b[H]=nil end end end;local V=0.85;local W=0.01;local X=0.0005;local Y=0.5;local Z=0.08;local _=0.03;local a0=0.02;local a1=0.5;local a2=0.5;local a3=0.01;function a.main()while not a.exitMain do local a4=0;local a5=0;local a6=0;local a7=0;local a8={}for H,F in pairs(b)do a.currentTask=F;a.uid=F.euid or F.uid;a.process=F.name;if F.status=="S"and a.EFI:getEpochMs()>=F.sleep then F.status="R"F.sleep=0 end;if F.status=="D"then if F.ksh then coroutine.resume(F.ksh)end end;if F.status=="R"then a4=a4+1;F.timeSlice=math.min(Y,math.max(X,a3/a4^V))if F.sigq and#F.sigq~=0 and F.sigh then local a9=coroutine.create(F.sigh)local aa,o=coroutine.resumeWithTimeout(a9,100,table.remove(F.sigq,1))if aa=="error"then F.sigd.error=o;F.sigd.active=false;F.sigh=nil;F.sigq=nil;F.sigd=nil elseif aa=="success"then if o=="syscall"then F.sigd.error="Cannot execute syscalls from signals"F.sigd.active=false;F.sigh=nil;F.sigq=nil;F.sigd=nil end end end;if F.status=="R"then local ab=a.EFI:getEpochMs()local N;if a.config.preempt then if not F.debugger then N={e(F.coro,F.timeSlice,table.unpack(F.syscallReturn))}else N={coroutine.resume(F.coro,table.unpack(F.syscallReturn))}end else N={coroutine.resume(F.coro,table.unpack(F.syscallReturn))}end;local ac=a.EFI:getEpochMs()-ab;F.lastTime=ac;F.totalTime=(F.totalTime or 0)+ac;F.numRuns=(F.numRuns or 0)+1;a8[#a8+1]=ac;a7=a7+ac;if ac<=X then a5=a5+1 end;if ac>=Y then a6=a6+1 end;if N[1]=="error"or N[1]==false then a.log("processHandlerException: "..tostring(N[2]),"ERROR",0xFF0000)F.status="Z"F.exit="processHandlerException: "..tostring(N[2])elseif N[1]=="timeout"then F.ivs=F.ivs+1;F.syscallReturn={}elseif N[1]=="success"or N[1]==true then F.vs=F.vs+1;if N[2]=="syscall"then local ad=N[3]if a.syscalls[ad]then if a.config.debugSyscalls then a.log("Task "..F.pid.." syscall: "..ad,"DBUG",0x00FFFF)for K=4,#N do a.log(" inval["..K-3 .."] = "..tostring(N[K]),"DBUG",0x00FFFF)end end;local ae={xpcall(a.syscalls[ad],debug.traceback,table.unpack(N,4))}if a.config.debugSyscalls then if not ae[1]then a.log("Task "..F.pid.." syscall "..ad.." failed: "..tostring(ae[2]),"ERROR",0xFF0000)else a.log("Task "..F.pid.." syscall "..ad.." ok, "..#ae-1 .." retvals","DBUG",0x00FFFF)for K=2,#ae do local L=type(ae[K])=="table"and table.serialize(ae[K])or tostring(ae[K])a.log(" retval["..K-1 .."] = "..L,"DBUG",0x00FFFF)end end end;if not ae[1]then F.syscallReturn={false,ae[2]}else F.syscallReturn={true,table.unpack(ae,2)}end else F.syscallReturn={false,"Unknown syscall: "..tostring(ad)}end end end end end end;local af=a4>0 and a7/a4 or 0;local ag=0;for C,ah in ipairs(a8)do ag=ag+(ah-af)^2 end;if a4>0 then ag=ag/a4 end;if a4>0 then local ai=a1*a5/a4-a2*a6/a4;local aj=W*a4^(V-1)/math.max(af,1e-8)a3=a3+Z*(aj-a3)+_*ai-a0*ag end;S()end end;local ak=a.syscalls;ak["spawn"]=c.spawn;ak["execspawn"]=c.execspawn;ak["exec"]=c.exec;ak["sleep"]=c.sleep;ak["getTask"]=c.getTask;ak["collect"]=c.collect;ak["kill"]=c.kill;ak["stop"]=c.stop;ak["continue"]=c.continue;ak["getpid"]=c.getpid;ak["getppid"]=c.getppid;ak["getTasks"]=c.getTasks;ak["setEnviron"]=c.setEnviron;ak["getEnviron"]=c.getEnviron;ak["exit"]=c.exit;ak["setuid"]=c.setuid;ak["getuid"]=c.getuid;ak["geteuid"]=c.geteuid;a._G.sleep=function(...)coroutine.yield("syscall","sleep",...)end;a.tasks=b;a.hpv=c diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/47_dbg.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/47_dbg.kmod deleted file mode 100644 index 04dd7b9..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/47_dbg.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local debug=debug;a._G.debug={getinfo=debug.getinfo,traceback=debug.traceback} diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/50_gpio.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/50_gpio.kmod deleted file mode 100644 index 43c6f13..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/50_gpio.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...local b=a.syscalls;a.gpio={}b["gpio_write"]=function(c,d)if a.gpio[c]then return a.gpio[c]("w",d)end end;b["gpio_writeAnalog"]=function(c,d)if a.gpio[c]then return a.gpio[c]("wa",d)end end;b["gpio_read"]=function(c)if a.gpio[c]then return a.gpio[c]("r")end end;b["gpio_readAnalog"]=function(c)if a.gpio[c]then return a.gpio[c]("ra")end end diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/70_stdlibadv.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/70_stdlibadv.kmod deleted file mode 100644 index b097403..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/70_stdlibadv.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...function print(...)local b={...}local c=""for d=1,#b do c=c..tostring(b[d]).."\t"end;c=c:sub(1,-2)syscall.write(1,c.."\n")end;function printf(e,...)local c=string.format(e,...)syscall.write(1,c.."\n")end;function printInline(...)local b={...}local c=""for d=1,#b do c=c..tostring(b[d]).."\t"end;c=c:sub(1,-2)syscall.write(1,c)end diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/90_init.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/90_init.kmod deleted file mode 100644 index a06234b..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/90_init.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...a.log("Loading init system...")a.log("InitPath: "..a.config.initPath)local b,c=pcall(a.vfs.access,a.config.initPath,"rx")if not b then a.PANIC("Init binary not executable: "..a.config.initPath.." ("..tostring(c)..")")end;local d=a.vfs.open(a.config.initPath,"r")if not d then a.panic("Failed to open "..a.config.initPath)end;local e=a.vfs.read(d,1024*1024*4)if not d then a.panic("Failed to read "..a.config.initPath)end;a.vfs.close(d)local f,g=load(e,"@sysinit","t",a._U)if not f then a.PANIC("Failed to load init system: "..g)end;a.tasks["1"]={coro=coroutine.create(function()local h,g=xpcall(f,debug.traceback,a)if not h then a.panic("Init system crashed: "..tostring(g))else a.panic("Init system exited: "..tostring(g))end end),name="sysinit",status="R",pid=1,tgid=1,uid=0,fd={},envars={},args={},exit="",sleep=0,ivs=0,vs=0,parent=a.kernelTask,siblings=a.kernelTask.children,children={},syscallReturn={},cwd="/",timeSlice=0,lastTime=0,totalTime=0,numRuns=0}a.log("created init task with PID 1")a.log("Initializing init system...") diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/91_login.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/91_login.kmod deleted file mode 100644 index 5a3b526..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/91_login.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...if not a.vfs.exists("/root")then a.vfs.mkdir("/root")end;a.processes.login=function()local b,c=pcall(a.hpv.execspawn,"/bin/login","login")if not b then a.log("Failed to exec /bin/login: "..tostring(c),"ERROR",0xFF0000)end end diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/92_setup.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/92_setup.kmod deleted file mode 100644 index 64f25bf..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/92_setup.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...if a.firstBoot then local b=a.vfs.P;local c=a.vfs.PERM;local d=b.OWNER_R+b.OWNER_W+b.GROUP_R+b.WORLD_R;local e=b.OWNER_R+b.OWNER_W+b.OWNER_X+b.GROUP_R+b.GROUP_X+b.WORLD_R+b.WORLD_X;local f=b.OWNER_R+b.OWNER_W+b.GROUP_R;local g=b.OWNER_R+b.OWNER_W;local h=c.RWXRWXRWX;local i=c.SUID_755;local j=0x02;local k=a.disks["$"]local function l(m,n,o,p,q,r)r=r or""local s=q%256;local t=math.floor(q/256)%256;local u=(o or 0)%256;local v=math.floor((o or 0)/256)%256;local w=(p or 0)%256;local x=math.floor((p or 0)/256)%256;return string.char(#m)..m..string.char(n,u,v,w,x,s,t)..string.char(#r)..r end;local y=0x00;local function z(A,B)local C=A;if C:sub(1,1)=="/"then C=C:sub(2)end;local D=C==""and".meta"or C.."/.meta"local E={}local F,G=pcall(function()return k:open(D,"r")end)if F and G then local H=G.read(65535)if G.close then G.close()end;E=a.vfs._parseMetafile and a.vfs._parseMetafile(H)or{}end;for I,J in ipairs(B)do local m=J[1]local n=J[2]or y;local o=J[3]or 0;local p=J[4]or 0;local q=J[5]or e;local r=J[6]or""E[m]={etype=n,owner=o,group=p,perms=q,cmeta=r}end;local K=string.char(j)for m,L in pairs(E)do K=K..l(m,L.etype or y,L.owner or 0,L.group or 0,L.perms or e,L.cmeta or"")end;local M,N=pcall(function()local O=k:open(D,"w")O.write(K)O.close()end)if not M then a.log("permissions: failed to write "..D..": "..tostring(N),"WARN",0xFF8800)end end;a.log("Seeding filesystem permissions...")z("/",{{"bin",y,0,0,e},{"boot",y,0,0,e},{"dev",y,0,0,h},{"etc",y,0,0,e},{"home",y,0,0,e},{"lib",y,0,0,e},{"proc",y,0,0,h},{"root",y,0,0,g},{"sbin",y,0,0,e},{"tmp",y,0,0,h},{"usr",y,0,0,e},{"var",y,0,0,h},{"opt",y,0,0,e}})z("/bin",{{"login",y,0,0,i},{"su",y,0,0,i},{"sudo",y,0,0,i}})z("/etc",{{"passwd",y,0,0,d},{"shadow",y,0,0,g},{"pam.d",y,0,0,g}})z("/etc/pam.d",{{"secret",y,0,0,g}})a.log("Filesystem permissions seeded.")end diff --git a/prod/Hyperion-kernel/lib/modules/hyperion/99_final.kmod b/prod/Hyperion-kernel/lib/modules/hyperion/99_final.kmod deleted file mode 100644 index b05feb5..0000000 --- a/prod/Hyperion-kernel/lib/modules/hyperion/99_final.kmod +++ /dev/null @@ -1 +0,0 @@ -local a=...a.allowGlobalOverwrites=false diff --git a/prod/bit32/lib/bit32 b/prod/bit32/lib/bit32 deleted file mode 100644 index 174055a..0000000 --- a/prod/bit32/lib/bit32 +++ /dev/null @@ -1 +0,0 @@ -local a={}local b=2^32;local c=2^31;local function d(e)return e%b end;local function f(e)e=d(e)local g={}for h=0,31 do local i=e%2;g[h]=i;e=(e-i)/2 end;return g end;local function j(g)local e=0;local k=1;for h=0,31 do if g[h]==1 then e=e+k end;k=k*2 end;return d(e)end;function a.band(...)local l={...}if#l==0 then return 0xFFFFFFFF end;local m=f(l[1])for h=2,#l do local i=f(l[h])for n=0,31 do m[n]=m[n]==1 and i[n]==1 and 1 or 0 end end;return j(m)end;function a.bor(...)local l={...}if#l==0 then return 0 end;local m=f(l[1])for h=2,#l do local i=f(l[h])for n=0,31 do m[n]=(m[n]==1 or i[n]==1)and 1 or 0 end end;return j(m)end;function a.bxor(...)local l={...}if#l==0 then return 0 end;local m=f(l[1])for h=2,#l do local i=f(l[h])for n=0,31 do m[n]=m[n]~=i[n]and 1 or 0 end end;return j(m)end;function a.bnot(e)local m=f(e)for h=0,31 do m[h]=m[h]==1 and 0 or 1 end;return j(m)end;function a.lshift(e,o)return d(d(e)*2^o)end;function a.rshift(e,o)return math.floor(d(e)/2^o)end;function a.arshift(e,o)e=d(e)if e>=c then return math.floor((e-b)/2^o)else return math.floor(e/2^o)end end;function a.lrotate(e,o)o=o%32;e=d(e)local p=e*2^o%b;local q=math.floor(e/2^(32-o))return d(p+q)end;function a.rrotate(e,o)o=o%32;e=d(e)local q=math.floor(e/2^o)local p=e*2^(32-o)%b;return d(p+q)end;function a.extract(e,r,s)s=s or 1;return a.band(a.rshift(e,r),2^s-1)end;function a.replace(e,t,r,s)s=s or 1;local u=a.lshift(2^s-1,r)e=a.band(e,a.bnot(u))return a.bor(e,a.lshift(t,r))end;return a diff --git a/prod/blake2s/lib/crypto/blake2s b/prod/blake2s/lib/crypto/blake2s deleted file mode 100644 index 0a4e761..0000000 --- a/prod/blake2s/lib/crypto/blake2s +++ /dev/null @@ -1 +0,0 @@ -local a=require("bit32")local b,c,d=a.band,a.bor,a.bxor;local e,f=a.rshift,a.lshift;local g=2^32;local function h(i,j)return c(e(i,j),f(i,32-j))end;local k={0x6A09E667,0xBB67AE85,0x3C6EF372,0xA54FF53A,0x510E527F,0x9B05688C,0x1F83D9AB,0x5BE0CD19}local l={{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},{14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3},{11,8,12,0,5,2,15,13,10,14,3,6,7,1,9,4},{7,9,3,1,13,12,11,14,2,6,5,10,4,0,15,8},{9,0,5,7,2,4,10,15,14,1,11,12,6,8,3,13},{2,12,6,10,0,11,8,3,4,13,7,5,15,14,1,9},{12,5,1,15,14,13,4,10,0,7,6,3,9,2,8,11},{13,11,7,14,12,1,3,9,5,0,15,4,8,6,2,10},{6,15,14,9,11,3,0,8,12,2,13,7,1,4,10,5},{10,2,8,4,7,6,1,5,15,11,9,14,3,12,13,0}}local function m(n,o,p,q,r,i,s)n[o]=(n[o]+n[p]+i)%g;n[r]=h(d(n[r],n[o]),16)n[q]=(n[q]+n[r])%g;n[p]=h(d(n[p],n[q]),12)n[o]=(n[o]+n[p]+s)%g;n[r]=h(d(n[r],n[o]),8)n[q]=(n[q]+n[r])%g;n[p]=h(d(n[p],n[q]),7)end;local function t(u,v,w,x)local n={}for y=1,8 do n[y]=u[y]end;for y=1,8 do n[y+8]=k[y]end;n[13]=d(n[13],w)if x then n[15]=d(n[15],0xFFFFFFFF)end;local z={}for y=0,15 do local A=y*4+1;z[y]=(v:byte(A)or 0)+(v:byte(A+1)or 0)*0x100+(v:byte(A+2)or 0)*0x10000+(v:byte(A+3)or 0)*0x1000000 end;for B=1,10 do local C=l[B]m(n,1,5,9,13,z[C[1]],z[C[2]])m(n,2,6,10,14,z[C[3]],z[C[4]])m(n,3,7,11,15,z[C[5]],z[C[6]])m(n,4,8,12,16,z[C[7]],z[C[8]])m(n,1,6,11,16,z[C[9]],z[C[10]])m(n,2,7,12,13,z[C[11]],z[C[12]])m(n,3,8,9,14,z[C[13]],z[C[14]])m(n,4,5,10,15,z[C[15]],z[C[16]])end;for y=1,8 do u[y]=d(u[y],n[y],n[y+8])end end;local function D(E,F)F=F or""local u={}for y=1,8 do u[y]=k[y]end;local G=32;u[1]=d(u[1],0x01010000+f(#F,8)+G)local w=0;if#F>0 then local v=F..string.rep("\0",64-#F)w=#F;t(u,v,w,false)end;for y=1,#E,64 do local v=E:sub(y,y+63)if#v<64 then v=v..string.rep("\0",64-#v)end;w=w+math.min(64,#E-y+1)t(u,v,w,y+64>#E)end;local H=""for y=1,8 do H=H..string.format("%08x",u[y])end;return H end;return D diff --git a/prod/deflate/lib/LibDeflate b/prod/deflate/lib/LibDeflate deleted file mode 100644 index 6b2a6ae..0000000 --- a/prod/deflate/lib/LibDeflate +++ /dev/null @@ -1 +0,0 @@ -local a;do local b="1.0.0-release"local c="LibDeflate "..b.." Copyright (C) 2018 Haoqian He.".." License GPLv3+: GNU GPL version 3 or later"if LibStub then local d,e="LibDeflate",-1;local f,g=LibStub:GetLibrary(d,true)if f and g and g>=e then return f else a=LibStub:NewLibrary(d,b)end else a={}end;a._VERSION=b;a._COPYRIGHT=c end;local assert=assert;local error=error;local pairs=pairs;local h=string.byte;local i=string.char;local j=string.find;local k=string.gsub;local l=string.sub;local m=table.concat;local n=table.sort;local tostring=tostring;local type=type;local o={}local p={}local q={}local r={}local s={}local t={}local u={}local v={}local w={}local x={3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258}local y={0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}local z={[0]=1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577}local A={[0]=0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}local B={16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}local C;local D;local E;local F;local G;local H;local I;local J;for K=0,255 do p[K]=i(K)end;do local L=1;for K=0,32 do o[K]=L;L=L*2 end end;for K=1,9 do q[K]={}for M=0,o[K+1]-1 do local N=0;local O=M;for P=1,K do N=N-N%2+((N%2==1 or O%2==1)and 1 or 0)O=(O-O%2)/2;N=N*2 end;q[K][M]=(N-N%2)/2 end end;do local Q=18;local R=16;local S=265;local T=1;for U=3,258 do if U<=10 then r[U]=U+254;t[U]=0 elseif U==258 then r[U]=285;t[U]=0 else if U>Q then Q=Q+R;R=R*2;S=S+4;T=T+1 end;local V=U-Q-1+R/2;r[U]=(V-V%(R/8))/(R/8)+S;t[U]=T;s[U]=V%(R/8)end end end;do u[1]=0;u[2]=1;w[1]=0;w[2]=0;local Q=3;local R=4;local W=2;local T=0;for X=3,256 do if X>R then Q=Q*2;R=R*2;W=W+2;T=T+1 end;u[X]=X<=Q and W or W+1;w[X]=T<0 and 0 or T;if R>=8 then v[X]=(X-R/2-1)%(R/4)end end end;local Y,Z,_,a0,a1;if bit~=nil then Y=bit.band;Z=bit.bnot;_=bit.bxor;a0=bit.blshift;a1=bit.blogic_rshift elseif bit32~=nil then Y=bit32.band;Z=bit32.bnot;_=bit32.bxor;a0=bit32.lshift;a1=bit32.rshift else _=function(Q,R)local a2=0;for K=32,0,-1 do local a3=2^K;local a4=false;local a5=false;if Q==0 then a2=a2+R;break end;if R==0 then a2=a2+Q;break end;if Q>=a3 then a4=true;Q=Q-a3 end;if R>=a3 then a5=true;R=R-a3 end;if not(a4 and a5)and(a4 or a5)then a2=a2+a3 end end;return a2 end;a0=function(a6,a7)local a8=a6*2^a7;return a8%2^32 end;a1=function(a6,a9)local a8=a6/2^a9;return math.floor(a8)end;Y=function(Q,R)local aa,S=1,0;while Q>0 and R>0 do local ab,ac=Q%2,R%2;if ab+ac>1 then S=S+aa end;Q,R,aa=(Q-ab)/2,(R-ac)/2,aa*2 end;return S end;Z=function(ad)return bxor(ad,2^(bits or floor(log(ad,2)))-1)end end;local ae=0xEDB88320;local function af(ag)local ah={}local V=setmetatable({},ah)function ah:__index(ai)local aj=ag(ai)V[ai]=aj;return aj end;return V end;local ak=af(function(K)local al=K;for P=1,8 do local R=Y(al,1)al=a1(al,1)if R==1 then al=_(al,ae)end end;return al end)local function am(an,al)al=Z(al or 0)local ao=a1(al,8)local ap=ak[_(al%256,an)]return Z(_(ao,ap))end;local function aq(ar,al)al=al or 0;for K=1,#ar do al=am(ar:byte(K),al)end;return al end;function a:CRC32(ar,al)if type(ar)=='string'then return aq(ar,al)else return am(ar,al)end end;function a:Adler32(as)if type(as)~="string"then error(("Usage: LibDeflate:Adler32(str):".." 'str' - string expected got '%s'."):format(type(as)),2)end;local at=#as;local K=1;local Q=1;local R=0;while K<=at-15 do local au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aI,aJ=h(as,K,K+15)R=(R+16*Q+16*au+15*av+14*aw+13*ax+12*ay+11*az+10*aA+9*aB+8*aC+7*aD+6*aE+5*aF+4*aG+3*aH+2*aI+aJ)%65521;Q=(Q+au+av+aw+ax+ay+az+aA+aB+aC+aD+aE+aF+aG+aH+aI+aJ)%65521;K=K+16 end;while K<=at do local ad=h(as,K,K)Q=(Q+ad)%65521;R=(R+Q)%65521;K=K+1 end;return(R*65536+Q)%4294967296 end;local function aK(aL,aM)return aL%4294967296==aM%4294967296 end;function a:CreateDictionary(as,at,aN)if type(as)~="string"then error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'str' - string expected got '%s'."):format(type(as)),2)end;if type(at)~="number"then error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'strlen' - number expected got '%s'."):format(type(at)),2)end;if type(aN)~="number"then error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'adler32' - number expected got '%s'."):format(type(aN)),2)end;if at~=#as then error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'strlen' does not match the actual length of 'str'.".." 'strlen': %u, '#str': %u .".." Please check if 'str' is modified unintentionally."):format(at,#as))end;if at==0 then error("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'str' - Empty string is not allowed.",2)end;if at>32768 then error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'str' - string longer than 32768 bytes is not allowed.".." Got %d bytes."):format(at),2)end;local aO=self:Adler32(as)if not aK(aN,aO)then error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'adler32' does not match the actual adler32 of 'str'.".." 'adler32': %u, 'Adler32(str)': %u .".." Please check if 'str' is modified unintentionally."):format(aN,aO))end;local aP={}aP.adler32=aN;aP.hash_tables={}aP.string_table={}aP.strlen=at;local aQ=aP.string_table;local aR=aP.hash_tables;aQ[1]=h(as,1,1)aQ[2]=h(as,2,2)if at>=3 then local K=1;local aS=aQ[1]*256+aQ[2]while K<=at-2-3 do local au,av,aw,ax=h(as,K+2,K+5)aQ[K+2]=au;aQ[K+3]=av;aQ[K+4]=aw;aQ[K+5]=ax;aS=(aS*256+au)%16777216;local V=aR[aS]if not V then V={}aR[aS]=V end;V[#V+1]=K-at;K=K+1;aS=(aS*256+av)%16777216;V=aR[aS]if not V then V={}aR[aS]=V end;V[#V+1]=K-at;K=K+1;aS=(aS*256+aw)%16777216;V=aR[aS]if not V then V={}aR[aS]=V end;V[#V+1]=K-at;K=K+1;aS=(aS*256+ax)%16777216;V=aR[aS]if not V then V={}aR[aS]=V end;V[#V+1]=K-at;K=K+1 end;while K<=at-2 do local ad=h(as,K+2)aQ[K+2]=ad;aS=(aS*256+ad)%16777216;local V=aR[aS]if not V then V={}aR[aS]=V end;V[#V+1]=K-at;K=K+1 end end;return aP end;local function aT(aP)if type(aP)~="table"then return false,("'dictionary' - table expected got '%s'."):format(type(aP))end;if type(aP.adler32)~="number"or type(aP.string_table)~="table"or type(aP.strlen)~="number"or aP.strlen<=0 or aP.strlen>32768 or aP.strlen~=#aP.string_table or type(aP.hash_tables)~="table"then return false,("'dictionary' - corrupted dictionary."):format(type(aP))end;return true,""end;local aU={[0]={false,nil,0,0,0},[1]={false,nil,4,8,4},[2]={false,nil,5,18,8},[3]={false,nil,6,32,32},[4]={true,4,4,16,16},[5]={true,8,16,32,32},[6]={true,8,16,128,128},[7]={true,8,32,128,256},[8]={true,32,128,258,1024},[9]={true,32,258,258,4096}}local function aV(as,aW,aP,aX,aY)if type(as)~="string"then return false,("'str' - string expected got '%s'."):format(type(as))end;if aW then local aZ,a_=aT(aP)if not aZ then return false,a_ end end;if aX then local b0=type(aY)if b0~="nil"and b0~="table"then return false,("'configs' - nil or table expected got '%s'."):format(type(aY))end;if b0=="table"then for ai,aj in pairs(aY)do if ai~="level"and ai~="strategy"then return false,("'configs' - unsupported table key in the configs: '%s'."):format(ai)elseif ai=="level"and not aU[aj]then return false,("'configs' - unsupported 'level': %s."):format(tostring(aj))elseif ai=="strategy"and aj~="fixed"and aj~="huffman_only"and aj~="dynamic"then return false,("'configs' - unsupported 'strategy': '%s'."):format(tostring(aj))end end end end;return true,""end;local b1=0;local b2=1;local b3=2;local b4=3;local function b5()local b6=0;local b7=0;local b8=0;local b9=0;local ba={}local bb={}local function bc(O,T)b7=b7+O*o[b8]b8=b8+T;b9=b9+T;if b8>=32 then b6=b6+1;ba[b6]=p[b7%256]..p[(b7-b7%256)/256%256]..p[(b7-b7%65536)/65536%256]..p[(b7-b7%16777216)/16777216%256]local bd=o[32-b8+T]b7=(O-O%bd)/bd;b8=b8-32 end end;local function be(as)for P=1,b8,8 do b6=b6+1;ba[b6]=i(b7%256)b7=(b7-b7%256)/256 end;b8=0;b6=b6+1;ba[b6]=as;b9=b9+#as*8 end;local function bf(bg)if bg==b4 then return b9 end;if bg==b2 or bg==b3 then local bh=(8-b8%8)%8;if b8>0 then b7=b7-o[b8]+o[b8+bh]for P=1,b8,8 do b6=b6+1;ba[b6]=p[b7%256]b7=(b7-b7%256)/256 end;b7=0;b8=0 end;if bg==b3 then b9=b9+bh;return b9 end end;local bi=m(ba)ba={}b6=0;bb[#bb+1]=bi;if bg==b1 then return b9 else return b9,m(bb)end end;return bc,be,bf end;local function bj(bk,bl,bm)bm=bm+1;bk[bm]=bl;local O=bl[1]local bn=bm;local bo=(bn-bn%2)/2;while bo>=1 and bk[bo][1]>O do local V=bk[bo]bk[bo]=bl;bk[bn]=V;bn=bo;bo=(bo-bo%2)/2 end end;local function bp(bk,bm)local bq=bk[1]local bl=bk[bm]local O=bl[1]bk[1]=bl;bk[bm]=bq;bm=bm-1;local bn=1;local br=bn*2;local bs=br+1;while br<=bm do local bt=bk[br]if bs<=bm and bk[bs][1]1 do local bM=bp(bk,bm)bm=bm-1;local bN=bp(bk,bm)bm=bm-1;local bO={bM[1]+bN[1],-1,bM,bN}bj(bk,bO,bm)bm=bm+1 end;local bP=0;local bQ={bk[1],0,0,0}local bR=1;local bS=1;bk[1][1]=0;while bS<=bR do local bl=bQ[bS]local T=bl[1]local bD=bl[2]local bt=bl[3]local bu=bl[4]if bt then bR=bR+1;bQ[bR]=bt;bt[1]=T+1 end;if bu then bR=bR+1;bQ[bR]=bu;bu[1]=T+1 end;bS=bS+1;if T>bz then bP=bP+1;T=bz end;if bD>=0 then bx[bD]=T;bH=bD>bH and bD or bH;bw[T]=(bw[T]or 0)+1 end end;if bP>0 then repeat local T=bz-1;while(bw[T]or 0)==0 do T=T-1 end;bw[T]=bw[T]-1;bw[T+1]=(bw[T+1]or 0)+2;bw[bz]=bw[bz]-1;bP=bP-2 until bP<=0;bS=1;for T=bz,1,-1 do local bT=bw[T]or 0;while bT>0 do local bD=bI[bS][2]bx[bD]=T;bT=bT-1;bS=bS+1 end end end;bJ=bv(bw,bx,by,bz)return bx,bJ,bH end end;local function bU(bV,bW,bX,bY)local bZ=0;local b_={}local c0={}local c1=0;local c2={}local c3=nil;local bL=0;bY=bY<0 and 0 or bY;local c4=bW+bY+1;for W=0,c4+1 do local U=W<=bW and(bV[W]or 0)or(W<=c4 and(bX[W-bW-1]or 0)or nil)if U==c3 then bL=bL+1;if U~=0 and bL==6 then bZ=bZ+1;b_[bZ]=16;c1=c1+1;c2[c1]=3;c0[16]=(c0[16]or 0)+1;bL=0 elseif U==0 and bL==138 then bZ=bZ+1;b_[bZ]=18;c1=c1+1;c2[c1]=127;c0[18]=(c0[18]or 0)+1;bL=0 end else if bL==1 then bZ=bZ+1;b_[bZ]=c3;c0[c3]=(c0[c3]or 0)+1 elseif bL==2 then bZ=bZ+1;b_[bZ]=c3;bZ=bZ+1;b_[bZ]=c3;c0[c3]=(c0[c3]or 0)+2 elseif bL>=3 then bZ=bZ+1;local c5=c3~=0 and 16 or(bL<=10 and 17 or 18)b_[bZ]=c5;c0[c5]=(c0[c5]or 0)+1;c1=c1+1;c2[c1]=bL<=10 and bL-3 or bL-11 end;c3=U;if U and U~=0 then bZ=bZ+1;b_[bZ]=U;c0[U]=(c0[U]or 0)+1;bL=0 else bL=1 end end end;return b_,c2,c0 end;local function c6(as,V,c7,c8,c9)local K=c7-c9;while K<=c8-15-c9 do V[K],V[K+1],V[K+2],V[K+3],V[K+4],V[K+5],V[K+6],V[K+7],V[K+8],V[K+9],V[K+10],V[K+11],V[K+12],V[K+13],V[K+14],V[K+15]=h(as,K+c9,K+15+c9)K=K+16 end;while K<=c8-c9 do V[K]=h(as,K+c9,K+c9)K=K+1 end;return V end;local function ca(cb,aQ,aR,cc,cd,c9,aP)local ce=aU[cb]local cf,cg,ch,ci,cj=ce[1],ce[2],ce[3],ce[4],ce[5]local ck=not cf and ch or 2147483646;local cl=cj-cj%4/4;local aS;local cm;local cn;local co=0;if aP then cm=aP.hash_tables;cn=aP.string_table;co=aP.strlen;assert(cc==1)if cd>=cc and co>=2 then aS=cn[co-1]*65536+cn[co]*256+aQ[1]local V=aR[aS]if not V then V={}aR[aS]=V end;V[#V+1]=-1 end;if cd>=cc+1 and co>=1 then aS=cn[co]*65536+aQ[1]*256+aQ[2]local V=aR[aS]if not V then V={}aR[aS]=V end;V[#V+1]=0 end end;aS=(aQ[cc-c9]or 0)*256+(aQ[cc+1-c9]or 0)local cp={}local cq=0;local cr={}local cs={}local ct=0;local cu={}local cv={}local cw=0;local cx={}local cy=0;local cz=false;local cA;local cB;local cC=0;local cD=0;local bS=cc;local cE=cd+(cf and 1 or 0)while bS<=cE do local cF=bS-c9;cA=cC;cB=cD;cC=0;aS=(aS*256+(aQ[cF+2]or 0))%16777216;local cG;local cH;local cI=aR[aS]local cJ;if not cI then cJ=0;cI={}aR[aS]=cI;if cm then cH=cm[aS]cG=cH and#cH or 0 else cG=0 end else cJ=#cI;cH=cI;cG=cJ end;if bS<=cd then cI[cJ+1]=bS end;if cG>0 and bS+2<=cd and(not cf or cA=cg and cl or cj;while cG>=1 and cK>0 do local c3=cH[cG]if bS-c3>32768 then break end;if c3=-257 then local cL=c3-c9;while M<258 and bS+M<=cd do if aQ[cL+M]==aQ[cF+M]then M=M+1 else break end end else local cL=co+c3;while M<258 and bS+M<=cd do if cn[cL+M]==aQ[cF+M]then M=M+1 else break end end end;if M>cC then cC=M;cD=bS-c3 end;if cC>=ci then break end end;cG=cG-1;cK=cK-1;if cG==0 and c3>0 and cm then cH=cm[aS]cG=cH and#cH or 0 end end end;if not cf then cA,cB=cC,cD end;if(not cf or cz)and(cA>3 or cA==3 and cB<4096)and cC<=cA then local W=r[cA]local cM=t[cA]local cN,cO,cP;if cB<=256 then cN=u[cB]cP=v[cB]cO=w[cB]else cN=16;cO=7;local Q=384;local R=512;while true do if cB<=Q then cP=(cB-R/2-1)%(R/4)break elseif cB<=R then cP=(cB-R/2-1)%(R/4)cN=cN+1;break else cN=cN+2;cO=cO+1;Q=Q*2;R=R*2 end end end;cq=cq+1;cp[cq]=W;cr[W]=(cr[W]or 0)+1;ct=ct+1;cs[ct]=cN;cu[cN]=(cu[cN]or 0)+1;if cM>0 then local cQ=s[cA]cw=cw+1;cv[cw]=cQ end;if cO>0 then cy=cy+1;cx[cy]=cP end;for K=bS+1,bS+cA-(cf and 2 or 1)do aS=(aS*256+(aQ[K-c9+2]or 0))%16777216;if cA<=ck then cI=aR[aS]if not cI then cI={}aR[aS]=cI end;cI[#cI+1]=K end end;bS=bS+cA-(cf and 1 or 0)cz=false elseif not cf or cz then local W=aQ[cf and cF-1 or cF]cq=cq+1;cp[cq]=W;cr[W]=(cr[W]or 0)+1;bS=bS+1 else cz=true;bS=bS+1 end end;cq=cq+1;cp[cq]=256;cr[256]=(cr[256]or 0)+1;return cp,cv,cr,cs,cx,cu end;local function cR(cr,cu)local cS,cT,bW=bF(cr,15,285)local cU,cV,bY=bF(cu,15,29)local cW,c2,cX=bU(cS,bW,cU,bY)local cY,cZ=bF(cX,7,18)local c_=0;for K=1,19 do local bD=B[K]local d0=cY[bD]or 0;if d0~=0 then c_=K end end;c_=c_-4;local d1=bW+1-257;local d2=bY+1-1;if d2<0 then d2=0 end;return d1,d2,c_,cY,cZ,cW,c2,cS,cT,cU,cV end;local function d3(cp,cs,c_,cY,cW,cS,cU)local d4=17;d4=d4+(c_+4)*3;for K=1,#cW do local W=cW[K]d4=d4+cY[W]if W>=16 then d4=d4+(W==16 and 2 or(W==17 and 3 or 7))end end;local d5=0;for K=1,#cp do local W=cp[K]local d6=cS[W]d4=d4+d6;if W>256 then d5=d5+1;if W>264 and W<285 then local d7=y[W-256]d4=d4+d7 end;local cN=cs[d5]local d8=cU[cN]d4=d4+d8;if cN>3 then local cO=(cN-cN%2)/2-1;d4=d4+cO end end end;return d4 end;local function d9(bc,da,cp,cv,cs,cx,d1,d2,c_,cY,cZ,cW,c2,cS,cT,cU,cV)bc(da and 1 or 0,1)bc(2,2)bc(d1,5)bc(d2,5)bc(c_,4)for K=1,c_+4 do local bD=B[K]local d0=cY[bD]or 0;bc(d0,3)end;local db=1;for K=1,#cW do local W=cW[K]bc(cZ[W],cY[W])if W>=16 then local dc=c2[db]bc(dc,W==16 and 2 or(W==17 and 3 or 7))db=db+1 end end;local d5=0;local dd=0;local de=0;for K=1,#cp do local df=cp[K]local bA=cT[df]local d6=cS[df]bc(bA,d6)if df>256 then d5=d5+1;if df>264 and df<285 then dd=dd+1;local dg=cv[dd]local d7=y[df-256]bc(dg,d7)end;local dh=cs[d5]local di=cV[dh]local d8=cU[dh]bc(di,d8)if dh>3 then de=de+1;local cP=cx[de]local cO=(dh-dh%2)/2-1;bc(cP,cO)end end end end;local function dj(cp,cs)local d4=3;local d5=0;for K=1,#cp do local W=cp[K]local d6=E[W]d4=d4+d6;if W>256 then d5=d5+1;if W>264 and W<285 then local d7=y[W-256]d4=d4+d7 end;local cN=cs[d5]d4=d4+5;if cN>3 then local cO=(cN-cN%2)/2-1;d4=d4+cO end end end;return d4 end;local function dk(bc,da,cp,cv,cs,cx)bc(da and 1 or 0,1)bc(1,2)local d5=0;local dd=0;local de=0;for K=1,#cp do local dl=cp[K]local bA=C[dl]local d6=E[dl]bc(bA,d6)if dl>256 then d5=d5+1;if dl>264 and dl<285 then dd=dd+1;local dg=cv[dd]local d7=y[dl-256]bc(dg,d7)end;local cN=cs[d5]local di=G[cN]bc(di,5)if cN>3 then de=de+1;local cP=cx[de]local cO=(cN-cN%2)/2-1;bc(cP,cO)end end end end;local function dm(cc,cd,b9)assert(cd-cc+1<=65535)local d4=3;b9=b9+3;local bh=(8-b9%8)%8;d4=d4+bh;d4=d4+32;d4=d4+(cd-cc+1)*8;return d4 end;local function dn(bc,be,da,as,cc,cd,b9)assert(cd-cc+1<=65535)bc(da and 1 or 0,1)bc(0,2)b9=b9+3;local bh=(8-b9%8)%8;if bh>0 then bc(o[bh]-1,bh)end;local dp=cd-cc+1;bc(dp,16)local dq=255-dp%256+(255-(dp-dp%256)/256)*256;bc(dq,16)be(as:sub(cc,cd))end;local function dr(aY,bc,be,bf,as,aP)local aQ={}local aR={}local da=nil;local cc;local cd;local ds;local b9=bf(b4)local at=#as;local c9;local cb;local dt;if aY then if aY.level then cb=aY.level end;if aY.strategy then dt=aY.strategy end end;if not cb then if at<2048 then cb=7 elseif at>65536 then cb=3 else cb=5 end end;while not da do if not cc then cc=1;cd=64*1024-1;c9=0 else cc=cd+1;cd=cd+32*1024;c9=cc-32*1024-1 end;if cd>=at then cd=at;da=true else da=false end;local cp,cv,cr,cs,cx,cu;local d1,d2,c_,cY,cZ,cW,c2,cS,cT,cU,cV;local du;local dv;local dw;if cb~=0 then c6(as,aQ,cc,cd+3,c9)if cc==1 and aP then local cn=aP.string_table;local dx=aP.strlen;for K=0,-dx+1<-257 and-257 or-dx+1,-1 do aQ[K]=cn[dx+K]end end;if dt=="huffman_only"then cp={}c6(as,cp,cc,cd,cc-1)cv={}cr={}cp[cd-cc+2]=256;for K=1,cd-cc+2 do local W=cp[K]cr[W]=(cr[W]or 0)+1 end;cs={}cx={}cu={}else cp,cv,cr,cs,cx,cu=ca(cb,aQ,aR,cc,cd,c9,aP)end;d1,d2,c_,cY,cZ,cW,c2,cS,cT,cU,cV=cR(cr,cu)du=d3(cp,cs,c_,cY,cW,cS,cU)dv=dj(cp,cs)end;dw=dm(cc,cd,b9)local dy=dw;dy=dv and dv0 and cd+1-V[1]>32768 then if dz==1 then else local dA={}local dB=0;for K=2,dz do M=V[K]if cd+1-M<=32768 then dB=dB+1;dA[dB]=M end end;aR[ai]=dA end end end end end end;local function dC(as,aP,aY)local bc,be,bf=b5()dr(aY,bc,be,bf,as,aP)local b9,dD=bf(b2)local bh=(8-b9%8)%8;return dD,bh end;local function dE(as,aP,aY)local bc,be,bf=b5()local dF=8;local dG=7;local dH=dG*16+dF;bc(dH,8)local dI=aP and 1 or 0;local dJ=2;local dK=dJ*64+dI*32;local dL=31-(dH*256+dK)%31;dK=dK+dL;bc(dK,8)if dI==1 then local aN=aP.adler32;local dM=aN%256;aN=(aN-dM)/256;local dN=aN%256;aN=(aN-dN)/256;local dO=aN%256;aN=(aN-dO)/256;local dP=aN%256;bc(dP,8)bc(dO,8)bc(dN,8)bc(dM,8)end;dr(aY,bc,be,bf,as,aP)bf(b3)local aN=a:Adler32(as)local dP=aN%256;aN=(aN-dP)/256;local dO=aN%256;aN=(aN-dO)/256;local dN=aN%256;aN=(aN-dN)/256;local dM=aN%256;bc(dM,8)bc(dN,8)bc(dO,8)bc(dP,8)local b9,dD=bf(b2)local bh=(8-b9%8)%8;return dD,bh end;function a:CompressDeflate(as,aY)local dQ,dR=aV(as,false,nil,true,aY)if not dQ then error("Usage: LibDeflate:CompressDeflate(str, configs): "..dR,2)end;return dC(as,nil,aY)end;function a:CompressDeflateWithDict(as,aP,aY)local dQ,dR=aV(as,true,aP,true,aY)if not dQ then error("Usage: LibDeflate:CompressDeflateWithDict".."(str, dictionary, configs): "..dR,2)end;return dC(as,aP,aY)end;function a:CompressZlib(as,aY)local dQ,dR=aV(as,false,nil,true,aY)if not dQ then error("Usage: LibDeflate:CompressZlib(str, configs): "..dR,2)end;return dE(as,nil,aY)end;function a:CompressZlibWithDict(as,aP,aY)local dQ,dR=aV(as,true,aP,true,aY)if not dQ then error("Usage: LibDeflate:CompressZlibWithDict".."(str, dictionary, configs): "..dR,2)end;return dE(as,aP,aY)end;local function dS()if os.epoch~=nil then return math.floor(os.epoch("utc")/1000)elseif os.time()<30 then return 0 else return os.time()end end;local function an(a6,R)return Y(a1(a6,R*8),0xFF)end;function a:CompressGzip(as,aY)local dQ,dR=aV(as,false,nil,true,aY)if not dQ then error("Usage: LibDeflate:CompressGzip(str, configs): "..dR,2)end;local a8,dT=dC(as,nil,aY)if a8==nil then return a8,dT end;local V=dS()local dU=0;local al=self:CRC32(as)local U=string.len(as)if aY~=nil and aY.level~=nil then if aY.level==0 then dU=0x04 elseif aY.level==9 then dU=0x02 end end;return i(0x1f,0x8b,8,0,an(V,0),an(V,1),an(V,2),an(V,3),dU,0xFF)..a8 ..i(an(al,0),an(al,1),an(al,2),an(al,3),an(U,0),an(U,1),an(U,2),an(U,3))end;local function dV(dW)local dX=dW;local dY=#dW;local dZ=1;local b8=0;local b7=0;local function d_(T)local bd=o[T]local W;if T<=b8 then W=b7%bd;b7=(b7-W)/bd;b8=b8-T else local e0=o[b8]local dN,dO,dP,e1=h(dX,dZ,dZ+3)b7=b7+((dN or 0)+(dO or 0)*256+(dP or 0)*65536+(e1 or 0)*16777216)*e0;dZ=dZ+4;b8=b8+32-T;W=b7%bd;b7=(b7-W)/bd end;return W end;local function e2(e3,ba,b6)assert(b8%8==0)local e4=b8/80 then if b8<15 and dX then local e0=o[b8]local dN,dO,dP,e1=h(dX,dZ,dZ+3)b7=b7+((dN or 0)+(dO or 0)*256+(dP or 0)*65536+(e1 or 0)*16777216)*e0;dZ=dZ+4;b8=b8+32 end;local bd=o[dy]b8=b8-dy;W=b7%bd;b7=(b7-W)/bd;W=q[dy][W]bL=e6[dy]if W0 and T285 then return-10 elseif bD<256 then b6=b6+1;ba[b6]=p[bD]elseif bD>256 then bD=bD-256;local T=x[bD]T=bD>=8 and T+d_(y[bD])or T;bD=e5(cU,el,em)if bD<0 or bD>29 then return-10 end;local X=z[bD]X=X>4 and X+d_(A[bD])or X;local eo=b6-X+1;if eo=-257 then for P=1,T do b6=b6+1;ba[b6]=ba[eo]eo=eo+1 end else eo=dx+eo;for P=1,T do b6=b6+1;ba[b6]=p[cn[eo]]eo=eo+1 end end end;if ea()<0 then return 2 end;if b6>=65536 then bb[#bb+1]=m(ba,"",1,32768)for K=32769,b6 do ba[K-32768]=ba[K]end;b6=b6-32768;ba[b6+1]=nil end until bD==256;ee.buffer_size=b6;return 0 end;local function ep(ee)local ba,b6,d_,e2,ea,eb,bb=ee.buffer,ee.buffer_size,ee.ReadBits,ee.ReadBytes,ee.ReaderBitlenLeft,ee.SkipToByteBoundary,ee.result_buffer;eb()local e3=d_(16)if ea()<0 then return 2 end;local eq=d_(16)if ea()<0 then return 2 end;if e3%256+eq%256~=255 then return-2 end;if(e3-e3%256)/256+(eq-eq%256)/256~=255 then return-2 end;b6=e2(e3,ba,b6)if b6<0 then return 2 end;if b6>=65536 then bb[#bb+1]=m(ba,"",1,32768)for K=32769,b6 do ba[K-32768]=ba[K]end;b6=b6-32768;ba[b6+1]=nil end;ee.buffer_size=b6;return 0 end;local function er(ee)return ei(ee,F,D,7,J,H,5)end;local function es(ee)local d_,e5=ee.ReadBits,ee.Decode;local et=d_(5)+257;local eu=d_(5)+1;local ev=d_(4)+4;if et>286 or eu>30 then return-3 end;local cY={}for K=1,ev do cY[B[K]]=d_(3)end;local ew,ex,ey,ez=ef(cY,18,7)if ew~=0 then return-4 end;local cS={}local cU={}local bS=0;while bSet+eu then return-6 end;while bD>0 do bD=bD-1;if bS7 then return nil,-13 end;local dK=d_(8)if ee.ReaderBitlenLeft()<0 then return nil,2 end;if(dH*256+dK)%31~=0 then return nil,-14 end;local dI=(dK-dK%32)/32%2;local dJ=(dK-dK%64)/64%4;if dI==1 then if not aP then return nil,-16 end;local dP=d_(8)local dO=d_(8)local dN=d_(8)local dM=d_(8)local aO=dP*16777216+dO*65536+dN*256+dM;if ee.ReaderBitlenLeft()<0 then return nil,2 end;if not aK(aO,aP.adler32)then return nil,-17 end end;local dD,eG=eE(ee)if not dD then return nil,eG end;ee.SkipToByteBoundary()local eL=d_(8)local eM=d_(8)local eN=d_(8)local eO=d_(8)if ee.ReaderBitlenLeft()<0 then return nil,2 end;local eP=eL*16777216+eM*65536+eN*256+eO;local eQ=a:Adler32(dD)if not aK(eP,eQ)then return nil,-15 end;local eI=ee.ReaderBitlenLeft()local eJ=(eI-eI%8)/8;return dD,eJ end;function a:DecompressDeflate(as)local dQ,dR=aV(as)if not dQ then error("Usage: LibDeflate:DecompressDeflate(str): "..dR,2)end;return eH(as)end;function a:DecompressDeflateWithDict(as,aP)local dQ,dR=aV(as,true,aP)if not dQ then error("Usage: LibDeflate:DecompressDeflateWithDict(str, dictionary): "..dR,2)end;return eH(as,aP)end;function a:DecompressZlib(as)local dQ,dR=aV(as)if not dQ then error("Usage: LibDeflate:DecompressZlib(str): "..dR,2)end;return eK(as)end;function a:DecompressZlibWithDict(as,aP)local dQ,dR=aV(as,true,aP)if not dQ then error("Usage: LibDeflate:DecompressZlibWithDict(str, dictionary): "..dR,2)end;return eK(as,aP)end;do E={}for eR=0,143 do E[eR]=8 end;for eR=144,255 do E[eR]=9 end;for eR=256,279 do E[eR]=7 end;for eR=280,287 do E[eR]=8 end;I={}for X=0,31 do I[X]=5 end;local eG;eG,F,D=ef(E,287,9)assert(eG==0)eG,J,H=ef(I,31,5)assert(eG==0)C=bv(F,E,287,9)G=bv(J,I,31,5)end;function a:DecompressGzip(as)local dQ,dR=aV(as)if not dQ then error("Usage: LibDeflate:DecompressGzip(str): "..dR,2)end;if h(string.sub(as,1,1))~=31 or h(string.sub(as,2,2))~=139 then return nil,-1 end;if Y(h(string.sub(as,4,4)),0xE0)~=0 then return nil,-3 end;if h(string.sub(as,3,3))~=8 then return nil,-4 end;local c9=10;if Y(h(string.sub(as,4,4)),4)==4 then c9=c9+h(string.sub(as,11,11))*256+h(string.sub(as,12,12))end;if Y(h(string.sub(as,4,4)),8)==8 then while h(string.sub(as,c9,c9))~=0 do c9=c9+1 end end;if Y(h(string.sub(as,4,4)),16)==16 then while h(string.sub(as,c9,c9))~=0 do c9=c9+1 end end;if Y(h(string.sub(as,4,4)),2)==2 then local eS=h(string.sub(as,c9+1,c9+1))*256+h(string.sub(as,c9,c9))local eT=Y(self:CRC32(string.sub(as,1,c9-1)),0xFFFF)if _(eS,eT)~=0xFFFF then return nil,-5 end;c9=c9+2 end;local a8,dT=eH(string.sub(as,c9+1,-8))if a8==nil then return a8,dT end;local eS=h(string.sub(as,-5,-5))*0x1000000+h(string.sub(as,-6,-6))*0x10000+h(string.sub(as,-7,-7))*256+h(string.sub(as,-8,-8))eS=Z(eS)local eT=self:CRC32(a8)if _(eS,eT)~=0xFFFFFFFF then return nil,-2 end;return a8 end;local eU={["\000"]="%z",["("]="%(",[")"]="%)",["."]="%.",["%"]="%%",["+"]="%+",["-"]="%-",["*"]="%*",["?"]="%?",["["]="%[",["]"]="%]",["^"]="%^",["$"]="%$"}local function eV(as)return as:gsub("([%z%(%)%.%%%+%-%*%?%[%]%^%$])",eU)end;function a:CreateCodec(eW,eX,eY)if type(eW)~="string"or type(eX)~="string"or type(eY)~="string"then error("Usage: LibDeflate:CreateCodec(reserved_chars,".." escape_chars, map_chars):".." All arguments must be string.",2)end;if eX==""then return nil,"No escape characters supplied."end;if#eW<#eY then return nil,"The number of reserved characters must be".." at least as many as the number of mapped chars."end;if eW==""then return nil,"No characters to encode."end;local eZ=eW..eX..eY;local e_={}for K=1,#eZ do local an=h(eZ,K,K)if e_[an]then return nil,"There must be no duplicate characters in the".." concatenation of reserved_chars, escape_chars and".." map_chars."end;e_[an]=true end;local f0={}local f1={}local f2={}local f3={}if#eY>0 then local f4={}local f5={}for K=1,#eY do local f6=l(eW,K,K)local f7=l(eY,K,K)f3[f6]=f7;f2[#f2+1]=f6;f5[f7]=f6;f4[#f4+1]=f7 end;f0[#f0+1]="(["..eV(m(f4)).."])"f1[#f1+1]=f5 end;local f8=1;local f9=l(eX,f8,f8)local fa=0;local f4={}local f5={}for K=1,#eZ do local S=l(eZ,K,K)if not f3[S]then while fa>=256 or e_[fa]do fa=fa+1;if fa>255 then f0[#f0+1]=eV(f9).."(["..eV(m(f4)).."])"f1[#f1+1]=f5;f8=f8+1;f9=l(eX,f8,f8)fa=0;f4={}f5={}if not f9 or f9==""then return nil,"Out of escape characters."end end end;local fb=p[fa]f3[S]=f9 ..fb;f2[#f2+1]=S;f5[fb]=S;f4[#f4+1]=fb;fa=fa+1 end;if K==#eZ then f0[#f0+1]=eV(f9).."(["..eV(m(f4)).."])"f1[#f1+1]=f5 end end;local fc={}local fd="(["..eV(m(f2)).."])"local fe=f3;function fc:Encode(as)if type(as)~="string"then error(("Usage: codec:Encode(str):".." 'str' - string expected got '%s'."):format(type(as)),2)end;return k(as,fd,fe)end;local ff=#f0;local fg="(["..eV(eW).."])"function fc:Decode(as)if type(as)~="string"then error(("Usage: codec:Decode(str):".." 'str' - string expected got '%s'."):format(type(as)),2)end;if j(as,fg)then return nil end;for K=1,ff do as=k(as,f0[K],f1[K])end;return as end;return fc end;local fh;local function fi()return a:CreateCodec("\000","\001","")end;function a:EncodeForWoWAddonChannel(as)if type(as)~="string"then error(("Usage: LibDeflate:EncodeForWoWAddonChannel(str):".." 'str' - string expected got '%s'."):format(type(as)),2)end;if not fh then fh=fi()end;return fh:Encode(as)end;function a:DecodeForWoWAddonChannel(as)if type(as)~="string"then error(("Usage: LibDeflate:DecodeForWoWAddonChannel(str):".." 'str' - string expected got '%s'."):format(type(as)),2)end;if not fh then fh=fi()end;return fh:Decode(as)end;local function fj()local fa={}for K=128,255 do fa[#fa+1]=p[K]end;local eW="sS\000\010\013\124%"..m(fa)return a:CreateCodec(eW,"\029\031","\015\020")end;local fk;function a:EncodeForWoWChatChannel(as)if type(as)~="string"then error(("Usage: LibDeflate:EncodeForWoWChatChannel(str):".." 'str' - string expected got '%s'."):format(type(as)),2)end;if not fk then fk=fj()end;return fk:Encode(as)end;function a:DecodeForWoWChatChannel(as)if type(as)~="string"then error(("Usage: LibDeflate:DecodeForWoWChatChannel(str):".." 'str' - string expected got '%s'."):format(type(as)),2)end;if not fk then fk=fj()end;return fk:Decode(as)end;local fl={[0]="a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9","(",")"}local fm={[97]=0,[98]=1,[99]=2,[100]=3,[101]=4,[102]=5,[103]=6,[104]=7,[105]=8,[106]=9,[107]=10,[108]=11,[109]=12,[110]=13,[111]=14,[112]=15,[113]=16,[114]=17,[115]=18,[116]=19,[117]=20,[118]=21,[119]=22,[120]=23,[121]=24,[122]=25,[65]=26,[66]=27,[67]=28,[68]=29,[69]=30,[70]=31,[71]=32,[72]=33,[73]=34,[74]=35,[75]=36,[76]=37,[77]=38,[78]=39,[79]=40,[80]=41,[81]=42,[82]=43,[83]=44,[84]=45,[85]=46,[86]=47,[87]=48,[88]=49,[89]=50,[90]=51,[48]=52,[49]=53,[50]=54,[51]=55,[52]=56,[53]=57,[54]=58,[55]=59,[56]=60,[57]=61,[40]=62,[41]=63}function a:EncodeForPrint(as)if type(as)~="string"then error(("Usage: LibDeflate:EncodeForPrint(str):".." 'str' - string expected got '%s'."):format(type(as)),2)end;local at=#as;local fn=at-2;local K=1;local ba={}local b6=0;while K<=fn do local au,av,aw=h(as,K,K+2)K=K+3;local b7=au+av*256+aw*65536;local fo=b7%64;b7=(b7-fo)/64;local fp=b7%64;b7=(b7-fp)/64;local fq=b7%64;local fr=(b7-fq)/64;b6=b6+1;ba[b6]=fl[fo]..fl[fp]..fl[fq]..fl[fr]end;local b7=0;local b8=0;while K<=at do local ad=h(as,K,K)b7=b7+ad*o[b8]b8=b8+8;K=K+1 end;while b8>0 do local fs=b7%64;b6=b6+1;ba[b6]=fl[fs]b7=(b7-fs)/64;b8=b8-6 end;return m(ba)end;function a:DecodeForPrint(as)if type(as)~="string"then error(("Usage: LibDeflate:DecodeForPrint(str):".." 'str' - string expected got '%s'."):format(type(as)),2)end;as=as:gsub("^[%c ]+","")as=as:gsub("[%c ]+$","")local at=#as;if at==1 then return nil end;local ft=at-3;local K=1;local ba={}local b6=0;while K<=ft do local au,av,aw,ax=h(as,K,K+3)au=fm[au]av=fm[av]aw=fm[aw]ax=fm[ax]if not(au and av and aw and ax)then return nil end;K=K+4;local b7=au+av*64+aw*4096+ax*262144;local fo=b7%256;b7=(b7-fo)/256;local fp=b7%256;local fq=(b7-fp)/256;b6=b6+1;ba[b6]=p[fo]..p[fp]..p[fq]end;local b7=0;local b8=0;while K<=at do local ad=h(as,K,K)ad=fm[ad]if not ad then return nil end;b7=b7+ad*o[b8]b8=b8+6;K=K+1 end;while b8>=8 do local an=b7%256;b6=b6+1;ba[b6]=p[an]b7=(b7-an)/256;b8=b8-8 end;return m(ba)end;local function fu()fk=nil;fh=nil end;a.internals={LoadStringToTable=c6,IsValidDictionary=aT,IsEqualAdler32=aK,_byte_to_6bit_char=fl,_6bit_to_byte=fm,InternalClearCache=fu}return a diff --git a/prod/deflate/lib/deflate b/prod/deflate/lib/deflate deleted file mode 100644 index 4e92342..0000000 --- a/prod/deflate/lib/deflate +++ /dev/null @@ -1,9 +0,0 @@ -local deflate=require("LibDeflate") -local lib={} -lib.compress=function(data) - return deflate:CompressDeflate(data) -end -lib.decompress=function(data) - return deflate:DecompressDeflate(data) -end -return lib \ No newline at end of file diff --git a/prod/hysh/bin/chattr b/prod/hysh/bin/chattr deleted file mode 100644 index a2524a3..0000000 --- a/prod/hysh/bin/chattr +++ /dev/null @@ -1 +0,0 @@ -local a=syscall.getTask(syscall.getpid()).name;local b={R=false,help=false}local c={}local d=nil;for e,f in ipairs({...})do if f:sub(1,2)=="--"then local g=f:sub(3)if b[g]==nil then print(a..": unrecognized option '"..f.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;b[g]=true elseif f:sub(1,1)=="-"and not f:match("^%-[%+%-]")then local h=true;for i=2,#f do local j=f:sub(i,i)if b[j]~=nil then b[j]=true else h=false;break end end;if not h then d=f end elseif f:sub(1,1)=="+"or f:sub(1,1)=="-"and f:match("^%-[a-zA-Z]")then d=f else table.insert(c,f)end end;if b.help then print("Usage: "..a.." [OPTION]... +-= ATTRS FILE...")print("Change file attributes on a filesystem.")print("")print("Attributes:")print(" i immutable: file cannot be modified, renamed, or deleted")print(" a append-only: file can only be appended to")print("")print("Operators: +attr add, -attr remove")print("Example: "..a.." +i /etc/passwd")print("")print("Options:")print(" -R operate on files and directories recursively")print(" --help display this help and exit")return end;if not d or#c<1 then print(a..": missing operand")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;local k=d:sub(1,1)local l=d:sub(2)if k~="+"and k~="-"then print(a..": invalid operator '"..k.."' (use + or -)")syscall.exit(1)return end;local function m(n)local o=pcall(function()return syscall.stat(n)end)and syscall.stat(n)if o then return o.xattr or""end;return""end;local p="|i"local q="|a"local function r(j)if j=="i"then return p elseif j=="a"then return q else return nil end end;local function s(n)local o=syscall.stat(n)if not o then print(a..": cannot stat '"..n.."': No such file or directory")return false end;if o.etype==0x01 then return true end;if not syscall.setxattr then print(a..": kernel does not expose setxattr syscall; cannot modify attributes")syscall.exit(1)return false end;local t=o.xattr or""for i=1,#l do local j=l:sub(i,i)local u=r(j)if not u then print(a..": unsupported attribute '"..j.."'")syscall.exit(1)return false end;local v=t:find(u,1,true)if k=="+"and not v then t=t..u elseif k=="-"and v then t=t:gsub(u:gsub("|","%%|"),"")end end;local w,x=pcall(syscall.setxattr,n,t)if not w then print(a..": cannot set attributes on '"..n.."': "..tostring(x))return false end;return true end;local function y(n)if not s(n)then return end;if syscall.type(n)=="directory"then local w,z=pcall(syscall.listdir,n)if w then for e,A in ipairs(z)do local B=n;if B:sub(-1)~="/"then B=B.."/"end;y(B..A)end end end end;local C=syscall.getcwd()local function D(E)if E:sub(1,1)~="/"then E=C.."/"..E end;return E end;if not syscall.setxattr then print(a..": kernel does not expose setxattr; attributes cannot be persisted")print(a..": add sys[\"setxattr\"] = vfs.setxattr to 10_vfs.kmod to enable this")syscall.exit(1)return end;local F=0;for i=1,#c do local n=D(c[i])if not syscall.exists(n)then print(a..": cannot access '"..c[i].."': No such file or directory")F=1 elseif b.R then y(n)else if not s(n)then F=1 end end end;syscall.exit(F) diff --git a/prod/hysh/bin/chgrp b/prod/hysh/bin/chgrp deleted file mode 100644 index 56ddee8..0000000 --- a/prod/hysh/bin/chgrp +++ /dev/null @@ -1 +0,0 @@ -local a=syscall.getTask(syscall.getpid()).name;local b={R=false,help=false}local c={}for d,e in ipairs({...})do if e:sub(1,2)=="--"then local f=e:sub(3)if b[f]==nil then print(a..": unrecognized option '"..e.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;b[f]=true elseif e:sub(1,1)=="-"then for g=2,#e do local f=e:sub(g,g)if b[f]==nil then print(a..": invalid option '-"..f.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;b[f]=true end else table.insert(c,e)end end;if b.help then print("Usage: "..a.." [OPTION]... GROUP FILE...")print("Change the group of each FILE to GROUP.")print("GROUP may be a group name or numeric ID.")print("")print("Options:")print(" -R operate on files and directories recursively")print(" --help display this help and exit")return end;if#c<2 then print(a..": missing operand")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;local h=c[1]local function i(j)local k=tonumber(j)if k then return k end;local l=syscall.getuidbyname and syscall.getuidbyname(j)if l then local m=syscall.getpasswd(l)if m then return m.gid end end;print(a..": invalid group: '"..j.."'")syscall.exit(1)end;local n=i(h)local function o(p)local q=syscall.stat(p)if not q then print(a..": cannot stat '"..p.."': no such file or directory")return false end;local r,s=pcall(syscall.chown,p,q.owner,n)if not r then local t=tostring(s)if t:find("EPERM")or t:find("EACCES")then t="operation not permitted (must be root)"elseif t:find("ENOENT")then t="no such file or directory"end;print(a..": cannot change group of '"..p.."': "..t)return false end;return true end;local function u(p)if not o(p)then return end;if syscall.type(p)=="directory"then local r,v=pcall(syscall.listdir,p)if r then for d,w in ipairs(v)do local x=p;if x:sub(-1)~="/"then x=x.."/"end;u(x..w)end end end end;local y=syscall.getcwd()local function z(A)if A:sub(1,1)~="/"then A=y.."/"..A end;return A end;local B=0;for g=2,#c do local p=z(c[g])if not syscall.exists(p)then print(a..": cannot access '"..c[g].."': No such file or directory")B=1 elseif b.R then u(p)else if not o(p)then B=1 end end end;syscall.exit(B) diff --git a/prod/hysh/bin/chmod b/prod/hysh/bin/chmod deleted file mode 100644 index e850739..0000000 --- a/prod/hysh/bin/chmod +++ /dev/null @@ -1 +0,0 @@ -local a=syscall.getTask(syscall.getpid()).name;local b={R=false,help=false}local c={}for d,e in ipairs({...})do if e:sub(1,2)=="--"then local f=e:sub(3)if b[f]==nil then print(a..": unrecognized option '"..e.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;b[f]=true elseif e:sub(1,1)=="-"then for g=2,#e do local f=e:sub(g,g)if b[f]==nil then print(a..": invalid option '-"..f.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;b[f]=true end else table.insert(c,e)end end;if b.help then print("Usage: "..a.." [OPTION]... MODE FILE...")print("Change the file mode bits of each FILE to MODE.")print("")print("MODE may be octal (e.g. 755) or symbolic (e.g. u+x, go-w, a=r).")print("")print("Octal bit layout (Hyperion):")print(" owner: r=32 w=16 x=512 group: r=8 w=4 x=256")print(" world: r=2 w=1 x=128 suid=64")print(" Common: 644=rw-r--r-- 755=rwxr-xr-x 700=rwx------")print("")print("Symbolic: [ugoa][+-=][rwxs] (comma-separated list)")print("")print("Options:")print(" -R change files and directories recursively")print(" --help display this help and exit")return end;if#c<2 then print(a..": missing operand")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;local h=c[1]local i={OWNER_R=32,OWNER_W=16,OWNER_X=512,GROUP_R=8,GROUP_W=4,GROUP_X=256,WORLD_R=2,WORLD_W=1,WORLD_X=128,SUID=64}local function j(k,l)return math.floor(k/2^l)%2==1 end;local function m(n)local o=tonumber(n,8)if not o then return nil end;local p=0;if j(o,8)then p=p+i.OWNER_R end;if j(o,7)then p=p+i.OWNER_W end;if j(o,6)then p=p+i.OWNER_X end;if j(o,5)then p=p+i.GROUP_R end;if j(o,4)then p=p+i.GROUP_W end;if j(o,3)then p=p+i.GROUP_X end;if j(o,2)then p=p+i.WORLD_R end;if j(o,1)then p=p+i.WORLD_W end;if j(o,0)then p=p+i.WORLD_X end;if j(o,11)then p=p+i.SUID end;return p end;local function q(r,s)local t=s;for u in(r..","):gmatch("([^,]+),")do local v,w=u:match("^([ugoa]*)([+%-=].+)$")if not v then print(a..": invalid mode: '"..u.."'")syscall.exit(1)return nil end;if v==""or v=="a"then v="ugo"end;local x=w:sub(1,1)local y=w:sub(2)local z=0;for g=1,#y do local A=y:sub(g,g)for B=1,#v do local C=v:sub(B,B)if A=="r"then if C=="u"then z=z+i.OWNER_R elseif C=="g"then z=z+i.GROUP_R elseif C=="o"then z=z+i.WORLD_R end elseif A=="w"then if C=="u"then z=z+i.OWNER_W elseif C=="g"then z=z+i.GROUP_W elseif C=="o"then z=z+i.WORLD_W end elseif A=="x"then if C=="u"then z=z+i.OWNER_X elseif C=="g"then z=z+i.GROUP_X elseif C=="o"then z=z+i.WORLD_X end elseif A=="s"then if C=="u"then z=z+i.SUID end end end end;if x=="+"then t=t+z-(t%(z+1)-t%z>0 and 0 or 0)t=t-t%1;local function D(E,F)local p,l=0,1;while E>0 or F>0 do if E%2==1 or F%2==1 then p=p+l end;E=math.floor(E/2)F=math.floor(F/2)l=l*2 end;return p end;t=D(t,z)elseif x=="-"then local function G(E,F)local p,l=0,1;while E>0 and F>0 do if E%2==1 and F%2==1 then p=p+l end;E=math.floor(E/2)F=math.floor(F/2)l=l*2 end;return p end;local function H(E,F)local p,l=0,1;while E>0 or F>0 do if E%2==1~=(F%2==1)then p=p+l end;E=math.floor(E/2)F=math.floor(F/2)l=l*2 end;return p end;t=H(t,G(t,z))elseif x=="="then local I=0;for B=1,#v do local C=v:sub(B,B)if C=="u"then I=I+i.OWNER_R+i.OWNER_W+i.OWNER_X+i.SUID elseif C=="g"then I=I+i.GROUP_R+i.GROUP_W+i.GROUP_X elseif C=="o"then I=I+i.WORLD_R+i.WORLD_W+i.WORLD_X end end;local function H(E,F)local p,l=0,1;while E>0 or F>0 do if E%2==1~=(F%2==1)then p=p+l end;E=math.floor(E/2)F=math.floor(F/2)l=l*2 end;return p end;local function G(E,F)local p,l=0,1;while E>0 and F>0 do if E%2==1 and F%2==1 then p=p+l end;E=math.floor(E/2)F=math.floor(F/2)l=l*2 end;return p end;local function D(E,F)local p,l=0,1;while E>0 or F>0 do if E%2==1 or F%2==1 then p=p+l end;E=math.floor(E/2)F=math.floor(F/2)l=l*2 end;return p end;t=H(t,G(t,I))t=D(t,z)else print(a..": invalid operator in mode: '"..u.."'")syscall.exit(1)return nil end end;return t end;local function J(r,s)if r:match("^[0-7]+$")then local K=m(r)if K then return K end end;return q(r,s)end;local function L(M)local N,O=pcall(syscall.stat,M)local s=0;if N then local n=syscall.stat(M)s=n and n.perms or 0 end;local P=J(h,s)if P==nil then return false end;local Q,R=pcall(syscall.chmod,M,P)if not Q then local S=tostring(R)if S:find("EACCES")or S:find("EPERM")then S="permission denied"elseif S:find("ENOENT")then S="no such file or directory"end;print(a..": cannot change permissions of '"..M.."': "..S)return false end;return true end;local function T(M)if not L(M)then return end;if syscall.type(M)=="directory"then local Q,U=pcall(syscall.listdir,M)if Q then for d,V in ipairs(U)do local W=M;if W:sub(-1)~="/"then W=W.."/"end;T(W..V)end end end end;local X=syscall.getcwd()local function Y(K)if K:sub(1,1)~="/"then K=X.."/"..K end;return K end;local Z=0;for g=2,#c do local M=Y(c[g])if not syscall.exists(M)then print(a..": cannot access '"..c[g].."': No such file or directory")Z=1 elseif b.R then T(M)else if not L(M)then Z=1 end end end;syscall.exit(Z) diff --git a/prod/hysh/bin/chown b/prod/hysh/bin/chown deleted file mode 100644 index 788e233..0000000 --- a/prod/hysh/bin/chown +++ /dev/null @@ -1 +0,0 @@ -local a=syscall.getTask(syscall.getpid()).name;local b={R=false,help=false}local c={}for d,e in ipairs({...})do if e:sub(1,2)=="--"then local f=e:sub(3)if b[f]==nil then print(a..": unrecognized option '"..e.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;b[f]=true elseif e:sub(1,1)=="-"then for g=2,#e do local f=e:sub(g,g)if b[f]==nil then print(a..": invalid option '-"..f.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;b[f]=true end else table.insert(c,e)end end;if b.help then print("Usage: "..a.." [OPTION]... OWNER[:GROUP] FILE...")print(" "..a.." [OPTION]... :GROUP FILE...")print("Change the owner and/or group of each FILE.")print("OWNER and GROUP may be names or numeric IDs.")print("")print("Options:")print(" -R operate on files and directories recursively")print(" --help display this help and exit")return end;if#c<2 then print(a..": missing operand")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;local h=c[1]local i,j;if h:sub(1,1)==":"then j=h:sub(2)else local k=h:find(":",1,true)if k then i=h:sub(1,k-1)j=h:sub(k+1)if j==""then j=nil end else i=h end end;local function l(m)if not m or m==""then return nil end;local n=tonumber(m)if n then return n end;local o=syscall.getuidbyname and syscall.getuidbyname(m)if o then return o end;print(a..": invalid user: '"..m.."'")syscall.exit(1)end;local function p(m)if not m or m==""then return nil end;local n=tonumber(m)if n then return n end;local o=syscall.getuidbyname and syscall.getuidbyname(m)if o then local q=syscall.getpasswd(o)if q then return q.gid end end;print(a..": invalid group: '"..m.."'")syscall.exit(1)end;local r=l(i)local s=p(j)if r==nil and s==nil then print(a..": no owner or group specified")syscall.exit(1)return end;local function t(u)local v=syscall.stat(u)if not v then print(a..": cannot stat '"..u.."': no such file or directory")return false end;local o=r~=nil and r or v.owner;local w=s~=nil and s or v.group;local x,y=pcall(syscall.chown,u,o,w)if not x then local z=tostring(y)if z:find("EPERM")or z:find("EACCES")then z="operation not permitted (must be root)"elseif z:find("ENOENT")then z="no such file or directory"end;print(a..": cannot change owner of '"..u.."': "..z)return false end;return true end;local function A(u)if not t(u)then return end;if syscall.type(u)=="directory"then local x,B=pcall(syscall.listdir,u)if x then for d,C in ipairs(B)do local D=u;if D:sub(-1)~="/"then D=D.."/"end;A(D..C)end end end end;local E=syscall.getcwd()local function F(G)if G:sub(1,1)~="/"then G=E.."/"..G end;return G end;local H=0;for g=2,#c do local u=F(c[g])if not syscall.exists(u)then print(a..": cannot access '"..c[g].."': No such file or directory")H=1 elseif b.R then A(u)else if not t(u)then H=1 end end end;syscall.exit(H) diff --git a/prod/hysh/bin/chroot b/prod/hysh/bin/chroot deleted file mode 100644 index 0fd573a..0000000 --- a/prod/hysh/bin/chroot +++ /dev/null @@ -1 +0,0 @@ -local a=syscall.getTask(syscall.getpid()).name;local b={}local c={help=false}for d,e in ipairs({...})do if e:sub(1,2)=="--"then local f=e:sub(3)if f=="help"then c.help=true else print(a..": unrecognized option '"..e.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end elseif e:sub(1,1)=="-"then print(a..": invalid option '"..e.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return else table.insert(b,e)end end;if c.help then print("Usage: "..a.." NEWROOT [COMMAND [ARG]...]")print("Run COMMAND with root directory set to NEWROOT.")print("If COMMAND is omitted, runs the current user's shell.")print("")print("Requires root (uid 0).")return end;if#b<1 then print(a..": missing operand")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;local g=syscall.geteuid and syscall.geteuid()or syscall.getuid()if g~=0 then print(a..": cannot change root directory: Permission denied")syscall.exit(1)return end;local h=b[1]if h:sub(1,1)~="/"then h=syscall.getcwd().."/"..h end;if not syscall.exists(h)then print(a..": cannot change root directory to '"..b[1].."': No such file or directory")syscall.exit(1)return end;if syscall.type(h)~="directory"then print(a..": '"..b[1].."': Not a directory")syscall.exit(1)return end;local i,j=pcall(syscall.chroot,h)if not i then print(a..": cannot change root directory to '"..b[1].."': "..tostring(j))syscall.exit(1)return end;local k;if#b>=2 then k=b[2]else local l=syscall.getuid()local m=syscall.getpasswd(l)k=m and m.shell or"/bin/hysh"end;local n={}for o=3,#b do table.insert(n,b[o])end;local p,q=pcall(syscall.exec,k,n)if not p then print(a..": failed to run command '"..k.."': "..tostring(q))syscall.exit(127)end diff --git a/prod/hysh/bin/help b/prod/hysh/bin/help deleted file mode 100644 index a814d38..0000000 --- a/prod/hysh/bin/help +++ /dev/null @@ -1 +0,0 @@ -local a={{name="cd",usage="cd [dir]",desc="Change working directory. Use '-' to return to previous directory.",flags={}},{name="pwd",usage="pwd",desc="Print current working directory.",flags={}},{name="ls",usage="ls [-alh] [dir]",desc="List directory contents. Coloured by type: dirs=blue, symlinks=cyan, executables=green.",flags={{"-a","Show hidden files (starting with .)"},{"-l","Long format: permissions, owner, group, size, mtime, name"},{"-h","Human-readable file sizes (with -l)"},{"--help","Display help and exit"}}},{name="find",usage="find [path] [-name PAT] [-type f|d|l] [-maxdepth N]",desc="Walk the filesystem tree and print matching paths.",flags={{"-name PAT","Match filename against shell glob (* and ?)"},{"-type f|d|l","Filter by file, directory, or symlink"},{"-maxdepth N","Descend at most N directory levels"},{"-mindepth N","Skip entries shallower than N levels"},{"-empty","Match empty files or empty directories"}}},{name="cp",usage="cp [-rRp] SOURCE... DEST",desc="Copy files or directories.",flags={{"-r,-R","Recurse into directories"},{"-p","Preserve permissions"},{"--help","Display help and exit"}}},{name="mv",usage="mv [-f] SOURCE... DEST",desc="Move or rename files and directories.",flags={{"-f","Do not prompt before overwriting (default)"},{"--help","Display help and exit"}}},{name="rm",usage="rm [-rRf] FILE...",desc="Remove files or directories.",flags={{"-r,-R","Recursively remove directories and their contents"},{"-f","Ignore nonexistent files, never prompt"},{"--help","Display help and exit"}}},{name="touch",usage="touch FILE...",desc="Create an empty file, or no-op if it already exists.",flags={}},{name="mkdir",usage="mkdir ",desc="Create a directory.",flags={}},{name="ln",usage="ln -s [-f] TARGET LINK",desc="Create a symbolic link. Multiple targets can be linked into a directory.",flags={{"-s","Create a symbolic link (required; hard links not supported)"},{"-f","Remove existing destination before creating link"},{"--help","Display help and exit"}}},{name="cat",usage="cat [file...]",desc="Print file(s) to stdout. Reads stdin if no file given.",flags={}},{name="head",usage="head [-n N] [file...]",desc="Print the first N lines of each file (default 10).",flags={{"-n N","Number of lines to print"},{"--help","Display help and exit"}}},{name="tail",usage="tail [-n N] [file...]",desc="Print the last N lines of each file (default 10).",flags={{"-n N","Number of lines to print"},{"--help","Display help and exit"}}},{name="wc",usage="wc [-lwc] [file...]",desc="Count lines, words, and bytes in files.",flags={{"-l","Print line count"},{"-w","Print word count"},{"-c","Print byte count"},{"--help","Display help and exit"}}},{name="grep",usage="grep [-ivnlcrR] PATTERN [file...]",desc="Search for lines matching a Lua pattern.",flags={{"-i","Ignore case"},{"-v","Invert: select non-matching lines"},{"-n","Prefix output with line numbers"},{"-l","Print only filenames that contain a match"},{"-c","Print count of matching lines per file"},{"-r,-R","Recurse into directories"},{"--help","Display help and exit"}}},{name="sed",usage="sed 's/PAT/REPL/' [file...]",desc="Stream editor. Applies substitution commands to each line.",flags={}},{name="sort",usage="sort [-rnu] [file...]",desc="Sort lines of text.",flags={{"-r","Reverse the sort order"},{"-n","Numeric sort"},{"-u","Suppress duplicate lines"},{"--help","Display help and exit"}}},{name="uniq",usage="uniq [-cdui] [input [output]]",desc="Filter adjacent duplicate lines.",flags={{"-c","Prefix each line with its repetition count"},{"-d","Print only lines that appear more than once"},{"-u","Print only lines that appear exactly once"},{"-i","Ignore case when comparing"},{"--help","Display help and exit"}}},{name="tee",usage="tee [-a] [file...]",desc="Copy stdin to stdout and to each FILE simultaneously.",flags={{"-a","Append to files instead of overwriting"},{"--help","Display help and exit"}}},{name="basename",usage="basename STRING [SUFFIX]",desc="Strip directory and optional suffix from a path.",flags={}},{name="dirname",usage="dirname STRING...",desc="Strip the last component from a path.",flags={}},{name="readlink",usage="readlink [-fenq] file...",desc="Print the target of a symbolic link.",flags={{"-f","Canonicalize: follow every symlink component"},{"-e","Like -f but all components must exist"},{"-n","Do not output trailing newline"},{"--help","Display help and exit"}}},{name="stat",usage="stat file...",desc="Display file type, size, owner, group, and permissions.",flags={{"--help","Display help and exit"}}},{name="chmod",usage="chmod [-R] MODE file...",desc="Change file permissions. MODE may be octal (755) or symbolic (u+x).",flags={{"-R","Recurse into directories"},{"--help","Display help and exit"}}},{name="chown",usage="chown [-R] USER[:GROUP] file...",desc="Change file owner and/or group.",flags={{"-R","Recurse into directories"},{"--help","Display help and exit"}}},{name="chgrp",usage="chgrp [-R] GROUP file...",desc="Change file group ownership.",flags={{"-R","Recurse into directories"},{"--help","Display help and exit"}}},{name="chattr",usage="chattr [+-=][attrs] file...",desc="Change file attributes.",flags={}},{name="echo",usage="echo [text...]",desc="Print arguments to stdout.",flags={}},{name="whoami",usage="whoami",desc="Print the current username.",flags={}},{name="id",usage="id [username]",desc="Print user identity (uid, gid).",flags={}},{name="ps",usage="ps",desc="List running tasks with pid, user, name, and status.",flags={}},{name="hostname",usage="hostname [NAME]",desc="Print or set the system hostname.",flags={}},{name="uname",usage="uname [-asnrm]",desc="Print system information (OS name, hostname, release, machine).",flags={{"-a","Print all fields"},{"-s","Kernel name"},{"-n","Node hostname"},{"-r","Kernel release"},{"-m","Machine hardware name"},{"--help","Display help and exit"}}},{name="df",usage="df [-h] [path...]",desc="Report filesystem disk space usage.",flags={{"-h","Human-readable sizes (K, M, G)"},{"--help","Display help and exit"}}},{name="stat",usage="stat file...",desc="Display file status: type, size, permissions, owner.",flags={}},{name="env",usage="env [KEY=VAL]... [CMD]",desc="Print the environment, or run a command with modified environment.",flags={}},{name="printenv",usage="printenv [NAME...]",desc="Print environment variable values (all if no names given).",flags={}},{name="sleep",usage="sleep N[smhd]",desc="Pause for N seconds (or minutes/hours/days with m/h/d suffix).",flags={}},{name="true",usage="true",desc="Do nothing, exit successfully (status 0).",flags={}},{name="false",usage="false",desc="Do nothing, exit unsuccessfully (status 1).",flags={}},{name="yes",usage="yes [text]",desc="Repeatedly print 'y' (or given text) until interrupted.",flags={}},{name="mount",usage="mount [-o loop] [SRC DEST | ID MNT]",desc="Mount a loop device or show all current mounts.",flags={{"-o loop","Attach SRC as a loop device and mount at DEST in one step"},{"--help","Display help and exit"}}},{name="umount",usage="umount [--no-detach] MOUNTPOINT | -l LOOPID",desc="Unmount a filesystem and auto-detach its loop device.",flags={{"--no-detach","Unmount but keep loop device attached"},{"-l LOOPID","Force-detach a loop device without unmounting"},{"--help","Display help and exit"}}},{name="losetup",usage="losetup [-dil] [path]",desc="Attach a directory or .hfs image as a loop device.",flags={{"-d ID","Detach loop device"},{"-i path","Force image mode (even without .hfs extension)"},{"-l","List all attached loop devices"},{"--help","Display help and exit"}}},{name="loimgcreate",usage="loimgcreate [-x] SRC DEST",desc="Pack a directory into a portable HFS image, or extract one.",flags={{"-x","Extract image to destination directory"},{"--help","Display help and exit"}}},{name="useradd",usage="useradd [-p pw] [-g gid] [-d home] [-s shell] [-M] ",desc="Create a new user account.",flags={{"-p pw","Set password"},{"-g gid","Set primary group id"},{"-d home","Set home directory (default /home/username)"},{"-s shell","Set login shell (default /bin/hysh)"},{"-M","Do not create home directory"}}},{name="userdel",usage="userdel [-r] ",desc="Delete a user account.",flags={{"-r","Also remove the user's home directory"}}},{name="usermod",usage="usermod [-l name] [-p pw] [-g gid] [-d home] [-s shell] [-LU] ",desc="Modify an existing user account.",flags={{"-l name","Rename the user"},{"-p pw","Set new password"},{"-g gid","Change primary group id"},{"-d home","Change home directory"},{"-s shell","Change login shell"},{"-L","Lock the account"},{"-U","Unlock the account"}}},{name="passwd",usage="passwd [username]",desc="Change a user password.",flags={}},{name="lsusers",usage="lsusers",desc="List all user accounts with uid, gid, home, and shell.",flags={}},{name="su",usage="su [username]",desc="Switch user. Defaults to root. Root can switch without a password.",flags={}},{name="sudo",usage="sudo [-u user] CMD [args...]",desc="Run a command as another user (default root).",flags={{"-u user","Run as the specified user (name or uid)"}}},{name="exit",usage="exit [N]",desc="Exit the shell with optional status code N.",flags={}},{name="clear",usage="clear",desc="Clear the terminal screen.",flags={}},{name="help",usage="help [command]",desc="Display this command reference. Pass a command name to filter.",flags={}},{name="lua",usage="lua",desc="Interactive Lua REPL prompt.",flags={}},{name="micro",usage="micro [file]",desc="Full-screen terminal text editor.",flags={}},{name="hfetch",usage="hfetch",desc="Display system information in a neofetch-style layout.",flags={}},{name="sysdump",usage="sysdump",desc="List all registered kernel syscalls.",flags={}},{name="chroot",usage="chroot DIR [CMD]",desc="Run a command with a different root directory.",flags={}}}do local b={}local c={}for d,e in ipairs(a)do if not b[e.name]then b[e.name]=true;table.insert(c,e)end end;a=c end;local f=7;local g=5;local h=1;local i=13;local j=3;local k=12;local l={}local function m(n,o)l[#l+1]={n,o or 1}end;m("HyperionOS Command Reference",f)m(string.rep("=",50),k)m("",1)local p={...}local q=p[1]local function r(e)m(e.name,g)m(" Usage: "..e.usage,h)m(" "..e.desc,i)if#e.flags>0 then for d,s in ipairs(e.flags)do m(" "..s[1],j)m(" "..s[2],i)end end;m("",1)end;if q then local t=false;for d,e in ipairs(a)do if e.name==q then r(e)t=true;break end end;if not t then m("help: unknown command '"..q.."'",2)m("Run 'help' with no arguments for the full list.",i)end else m("Run 'help ' for details on a specific command.",i)m("",1)for d,e in ipairs(a)do r(e)end end;local u=syscall.devctl(1,"size")local v=tonumber(u:match("^(%d+)"))or 51;local w=tonumber(u:match(";(%d+)"))or 19;local x=w-2;local y=0;local z=#l;local A=true;local function B()syscall.devctl(1,"clear")syscall.devctl(1,"spos",1,1)for C=1,x do local D=y+C;if D<=z then local n,o=l[D][1],l[D][2]syscall.devctl(1,"sfgc",o)if#n>v then n=n:sub(1,v)end;syscall.write(1,n.."\n")else syscall.write(1,"\n")end end;syscall.devctl(1,"sfgc",0x000000)syscall.devctl(1,"sbgc",0xDBDBDB)local E=math.floor(math.min(100,(y+x)/z*100))local F=string.format(" help -- line %d/%d (%d%%) [up/down: scroll q: quit] ",y+1,z,E)if#F>v then F=F:sub(1,v)end;syscall.devctl(1,"spos",1,w)syscall.write(1,F..string.rep(" ",v-#F))syscall.devctl(1,"sfgc",0xFFFFFF)syscall.devctl(1,"sbgc",0x000000)A=false end;if z<=x then syscall.devctl(1,"clear")syscall.devctl(1,"spos",1,1)for d,G in ipairs(l)do syscall.devctl(1,"sfgc",G[2])syscall.write(1,G[1].."\n")end;syscall.devctl(1,"sfgc",0xFFFFFF)return end;B()while true do local H=syscall.read(0)if not H or H==""then elseif H=="q"or H=="Q"then break elseif H=="\17"then if y>0 then y=y-1;A=true end elseif H=="\18"then if y+x0 then q[#q+1]=p.."d"end;if o>0 then q[#q+1]=o.."h"end;if n>0 then q[#q+1]=n.."m"end;q[#q+1]=m.."s"return table.concat(q," ")end;local r=syscall.getHost()or"Unknown"local s=r:match("ComputerCraft ([%d%.]+)")or r;local t={{nil,j},{nil,string.rep("-",#j)},{"OS",syscall.version()or"Unknown"},{"Host",s},{"Arch",syscall.arch()or"Unknown"},{"Uptime",k(syscall.getUptime()or 0)},{"Tasks",tostring(#(syscall.getTasks()or{}))},{"Shell",syscall.getEnviron("SHELL")or"Unknown"},{"Terminal","tty1"},{"UID",tostring(syscall.getuid())},{"Packages","n/a (spm)"}}local u={".. *. .. "," *= +@* +* "," .@#. -@@@= :#@. "," =@@+ *@@@# +@@= "," %@@%: *@@@# -%@@% "," :@@@@+ *@@@# .*@@@@: "," :*@@@%- *@@@# -@@@@*: "," =%@@#. *@@@# .#@@%= "," :=. :*@@= *@@@# =@@+: .=: "," %@#=..*# +@@@# #*..=#@# "," .@@@@+=# .%@%: #=+@@@@. "," .....=# -@= *+...:. "," -*%*-@= - =@-*%*- "," -@*. -@%. :%@- :*@- "," .#@#@* "," -#- "," "}local v=math.max(#u,#t)for w=1,v do local x=u[w]or string.rep(" ",36)f(a)printInline(x)f(c)printInline("| ")local y=t[w]if y then if y[1]==nil and w==1 then f(e)printInline(y[2])elseif y[1]==nil and w==2 then f(d)printInline(y[2])elseif y[1]then f(c)printInline(y[1]..": ")f(b)printInline(y[2])end end;f(b)print("")end diff --git a/prod/hysh/bin/hysh b/prod/hysh/bin/hysh deleted file mode 100644 index 5a0e737..0000000 --- a/prod/hysh/bin/hysh +++ /dev/null @@ -1 +0,0 @@ -syscall.open("/dev/tty/1","r")syscall.open("/dev/tty/1","w")syscall.open("/dev/null","w")local a,b=xpcall(function()local c=require("fs")syscall.devctl(1,"clear")syscall.devctl(1,"sfgc",0xFFFFFF)syscall.devctl(1,"spos",1,1)print("HyperionOS hysh Shell")local d=(syscall.getUsername()or"Unknown").."@"..(syscall.getHostname()or"Unknown")local e={}local f=false;syscall.setEnviron("SHELL","hysh")syscall.setEnviron("PATH","/bin/")local g=syscall.getEnviron("HOME")if g and g~=""then local h=pcall(syscall.chdir,g)if not h then syscall.chdir("/")end else syscall.chdir("/")end;local i=""local j={0xFFFFFF,0xFF0000,0x00FF00,0x0000FF,0x00FFFF,0xFF00FF,0xFFFF00,0xFF6D00,0x6DFF55,0x24FFFF,0x924900,0x6D6D55,0xDBDBAA,0x6D00FF,0xB6FF00,0x000000}for k=1,16 do syscall.devctl(1,"sbgc",j[k])printInline(" ")end;print("\n")syscall.sigcatch(function(l)if l==1 then f=true end end)local function m(n)if not n or n==""then return syscall.getcwd()end;if n:sub(1,1)~="/"then n=syscall.getcwd().."/"..n end;local o={}for p in n:gmatch("[^/]+")do if p==".."then if#o>0 then table.remove(o)end elseif p~="."then table.insert(o,p)end end;return"/"..table.concat(o,"/")end;local function q(n)n=n:gsub("/$","")return n:match("([^/]+)$")or n end;local function r(n)n=n:gsub("/$","")local s=n:match("^(.*)/[^/]+$")if not s then return"."end;if s==""then return"/"end;return s end;local function t(u)local v={}while true do local h,w=pcall(syscall.read,u,65536)if not h or not w or w==""then break end;v[#v+1]=w end;return table.concat(v)end;local function x(y)local h,u=pcall(syscall.open,y,"r")if not h then return nil,u end;local z=t(u)pcall(syscall.close,u)return z end;local function A(y,z)local h,u=pcall(syscall.open,y,"w")if not h then return false,u end;pcall(syscall.write,u,z)pcall(syscall.close,u)return true end;local function B(C,D,E)local F={}local G={}E=E or{}local k=1;while k<=#C do local H=C[k]if H=="--"then for I=k+1,#C do G[#G+1]=C[I]end;break elseif H:sub(1,2)=="--"then local J=H:sub(3)if E[J]~=nil then F[J]=true else F["_unknown"]=H end elseif H:sub(1,1)=="-"and#H>1 then for K=2,#H do local L=H:sub(K,K)if D:find(L,1,true)then F[L]=true else F["_unknown"]="-"..L end end else G[#G+1]=H end;k=k+1 end;return F,G end;local function M(N,O)local P=1;while P<=#N do local Q=N:find("\n",P,true)if Q then O(N:sub(P,Q-1))P=Q+1 else O(N:sub(P))break end end end;local function R(N)local S={}M(N,function(T)S[#S+1]=T end)return S end;local function U(V,W)local z,X=x(V)if not z then return false,X end;local h,Y=A(W,z)if not h then return false,Y end;return true end;local function Z(y)local v=syscall.type(y)if v=="directory"then local h,_=pcall(syscall.listdir,y)if h then for a0,a1 in ipairs(_)do Z(y:gsub("/$","").."/"..a1)end end end;if v then pcall(syscall.remove,y)end end;local function a2(V,W)pcall(syscall.mkdir,W)local h,_=pcall(syscall.listdir,V)if not h then return end;for a0,a1 in ipairs(_)do local a3=V:gsub("/$","").."/"..a1;local s=W:gsub("/$","").."/"..a1;local v=syscall.type(a3)if v=="directory"then a2(a3,s)elseif v=="file"then U(a3,s)elseif v=="symlink"then local a4,a5=pcall(syscall.readlink,a3)if a4 then pcall(syscall.remove,s)pcall(syscall.symlink,a5,s)end end end end;local a6={}a6.cd=function(y)local a7=syscall.getcwd()local a8=y or""if a8=="-"then if i==""then print("hysh: cd: no previous directory")return end;print(i)local a9=i;i=a7;syscall.chdir(a9)return end;local aa=m(a8)if aa:sub(-1)~="/"then aa=aa.."/"end;if not c.isDir(aa)then print("hysh: cd: "..a8 ..": No such directory")return end;i=a7;syscall.chdir(aa)end;a6.exit=function(ab)syscall.exit(tonumber(ab)or 0)end;a6.echo=function(...)local G={...}local ac=false;local ad=1;if G[1]=="-n"then ac=true;ad=2 end;local ae=table.concat(G," ",ad)if ac then printInline(ae)else print(ae)end end;a6.pwd=function()print(syscall.getcwd())end;a6["true"]=function()end;a6["false"]=function()end;a6.sleep=function(...)local G={...}if#G==0 then print("sleep: missing operand")return end;local af=0;for a0,ag in ipairs(G)do local ac,ah=ag:match("^([%d%.]+)([smhd]?)$")if not ac then print("sleep: invalid time '"..ag.."'")return end;ac=tonumber(ac)if ah=="m"then ac=ac*60 elseif ah=="h"then ac=ac*3600 elseif ah=="d"then ac=ac*86400 end;af=af+ac end;sleep(af)end;a6.clear=function()syscall.devctl(1,"clear")syscall.devctl(1,"sfgc",0xFFFFFF)syscall.devctl(1,"spos",1,1)end;a6.whoami=function()print(syscall.getUsername()or"unknown")end;a6.hostname=function(...)local G={...}if#G==0 then print(syscall.getHostname()or"unknown")else local h,X=pcall(syscall.setHostname,G[1])if not h then print("hostname: "..tostring(X))end end end;a6.uname=function(...)local F,a0=B({...},"asnrm")local ai=F.a;local o={}local aj={}for ak in string.gmatch(syscall.version(),"%S+")do table.insert(aj,ak)end;if ai or F.s or not F.s and not F.n and not F.r and not F.m then o[#o+1]=aj[1]end;if ai or F.n then o[#o+1]=syscall.getHostname()or"hyperion"end;if ai or F.r then o[#o+1]=aj[2]end;if ai or F.m then o[#o+1]="virtual"end;print(table.concat(o," "))end;a6.printenv=function(...)local G={...}local al={"PATH","HOME","USER","SHELL","TERM","HOSTNAME","PWD","OLDPWD","LANG","TZ","EDITOR"}if#G==0 then for a0,K in ipairs(al)do local h,H=pcall(syscall.getEnviron,K)if h and H then print(K.."="..H)end end else for a0,K in ipairs(G)do local h,H=pcall(syscall.getEnviron,K)if h and H then print(H)end end end end;a6.env=function(...)local G={...}local k=1;while k<=#G and G[k]:match("^[%w_]+=")do local K,H=G[k]:match("^([^=]+)=(.*)")pcall(syscall.setEnviron,K,H)k=k+1 end;if k>#G then a6.printenv()end end;a6.touch=function(...)local a0,G=B({...},"amc")if#G==0 then print("touch: missing operand")return end;for a0,ag in ipairs(G)do local y=m(ag)if not syscall.exists(y)then local h,u=pcall(syscall.open,y,"w")if h then pcall(syscall.close,u)else print("touch: cannot create '"..ag.."': "..tostring(u))end end end end;a6.mkdir=function(...)local F,G=B({...},"p")if#G==0 then print("mkdir: missing operand")return end;for a0,ag in ipairs(G)do local y=m(ag)if y:sub(-1)~="/"then y=y.."/"end;if c.isDir(y)then print("mkdir: cannot create '"..ag.."': Directory exists")return end;local h,X=pcall(syscall.mkdir,y)if not h then print("mkdir: cannot create '"..ag.."': "..tostring(X))end end end;a6.rm=function(...)local F,G=B({...},"rRf")if#G==0 then print("rm: missing operand")return end;local am=F.r or F.R;for a0,ag in ipairs(G)do local y=m(ag)local v=syscall.type(y)if not v then if not F.f then print("rm: cannot remove '"..ag.."': No such file or directory")end elseif v=="directory"then if not am then print("rm: cannot remove '"..ag.."': Is a directory")else Z(y)end else local h,X=pcall(syscall.remove,y)if not h then print("rm: cannot remove '"..ag.."': "..tostring(X))end end end end;a6.cp=function(...)local F,G=B({...},"rRp")if#G<2 then print("cp: missing operand")return end;local am=F.r or F.R;local W=m(G[#G])local an=syscall.type(W)=="directory"if#G>2 and not an then print("cp: target '"..G[#G].."' is not a directory")return end;for k=1,#G-1 do local V=m(G[k])local v=syscall.type(V)if not v then print("cp: '"..G[k].."': No such file or directory")elseif v=="directory"then if not am then print("cp: omitting directory '"..G[k].."'")else a2(V,an and W:gsub("/$","").."/"..q(G[k])or W)end else local s=an and W:gsub("/$","").."/"..q(G[k])or W;local h,X=U(V,s)if not h then print("cp: '"..G[k].."': "..tostring(X))end end end end;a6.mv=function(...)local F,G=B({...},"f")if#G<2 then print("mv: missing operand")return end;local W=m(G[#G])local an=syscall.type(W)=="directory"if#G>2 and not an then print("mv: target '"..G[#G].."' is not a directory")return end;for k=1,#G-1 do local V=m(G[k])local v=syscall.type(V)if not v then print("mv: '"..G[k].."': No such file or directory")else local s=an and W:gsub("/$","").."/"..q(G[k])or W;if v=="directory"then a2(V,s)Z(V)else local h,X=U(V,s)if h then pcall(syscall.remove,V)else print("mv: '"..G[k].."': "..tostring(X))end end end end end;a6.cat=function(...)local G={...}if#G==0 then while true do local h,w=pcall(syscall.read,0,4096)if not h or not w or w==""then break end;printInline(w)end;print("")return end;for a0,ag in ipairs(G)do local y=m(ag)if not syscall.exists(y)then print("cat: "..ag..": No such file or directory")else local h,u=pcall(syscall.open,y,"r")if not h then print("cat: "..ag..": "..tostring(u))else while true do local a4,w=pcall(syscall.read,u,65536)if not a4 or not w or w==""then break end;printInline(w)end;pcall(syscall.close,u)end end end end;a6.head=function(...)local ao={...}local ac=10;local ap={}local k=1;while k<=#ao do local H=ao[k]if H=="-n"then k=k+1;ac=tonumber(ao[k])or 10 elseif H:match("^%-n%d+$")then ac=tonumber(H:sub(3))elseif H:match("^%-%d+$")then ac=tonumber(H:sub(2))elseif H:sub(1,1)~="-"or H=="-"then ap[#ap+1]=H end;k=k+1 end;local aq=#ap>1;local function ar(N,as)if aq then syscall.devctl(1,"sfgc",0x0000FF)print("==> "..as.." <==")syscall.devctl(1,"sfgc",0xFFFFFF)end;local at=0;for au in(N.."\n"):gmatch("([^\n]*)\n")do if at>=ac then break end;print(au)at=at+1 end end;if#ap==0 then ar(t(0),"stdin")else for a0,ag in ipairs(ap)do if ag=="-"then ar(t(0),"stdin")else local z,X=x(m(ag))if not z then print("head: "..ag..": "..tostring(X))else ar(z,ag)end end end end end;a6.tail=function(...)local ao={...}local ac=10;local ap={}local k=1;while k<=#ao do local H=ao[k]if H=="-n"then k=k+1;ac=tonumber(ao[k])or 10 elseif H:match("^%-n%d+$")then ac=tonumber(H:sub(3))elseif H:match("^%-%d+$")then ac=tonumber(H:sub(2))elseif H:sub(1,1)~="-"or H=="-"then ap[#ap+1]=H end;k=k+1 end;local aq=#ap>1;local function av(N,as)if aq then syscall.devctl(1,"sfgc",0x0000FF)print("==> "..as.." <==")syscall.devctl(1,"sfgc",0xFFFFFF)end;local S=R(N)local ad=math.max(1,#S-ac+1)for I=ad,#S do print(S[I])end end;if#ap==0 then av(t(0),"stdin")else for a0,ag in ipairs(ap)do if ag=="-"then av(t(0),"stdin")else local z,X=x(m(ag))if not z then print("tail: "..ag..": "..tostring(X))else av(z,ag)end end end end end;a6.wc=function(...)local F,G=B({...},"lwc")local aw=not F.l and not F.w and not F.c;if aw then F.l=true;F.w=true;F.c=true end;local function at(N)local T,ax,ay=0,0,#N;for a0 in N:gmatch("\n")do T=T+1 end;for a0 in N:gmatch("%S+")do ax=ax+1 end;return T,ax,ay end;local function az(T,ax,L,aA)local n={}if F.l then n[#n+1]=string.format("%7d",T)end;if F.w then n[#n+1]=string.format("%7d",ax)end;if F.c then n[#n+1]=string.format("%7d",L)end;if aA then n[#n+1]=" "..aA end;print(table.concat(n))end;local aB,aC,aD=0,0,0;if#G==0 then local T,ax,L=at(t(0))az(T,ax,L)else for a0,ag in ipairs(G)do local z,X=x(m(ag))if not z then print("wc: "..ag..": "..tostring(X))else local T,ax,L=at(z)az(T,ax,L,ag)aB=aB+T;aC=aC+ax;aD=aD+L end end;if#G>1 then az(aB,aC,aD,"total")end end end;a6.grep=function(...)local F,G=B({...},"ivnlcrR",{["ignore-case"]=true,["invert-match"]=true})if#G==0 then print("grep: missing pattern")return end;local aE=G[1]if F.i or F["ignore-case"]then aE=aE:lower()end;local am=F.r or F.R;local aF=false;local function aG(N,as,aH)local at=0;local aI=0;local aJ=false;M(N,function(au)aI=aI+1;local aK=(F.i or F["ignore-case"])and au:lower()or au;local aL=aK:find(aE)~=nil;if F.v or F["invert-match"]then aL=not aL end;if aL then at=at+1;aJ=true;aF=true;if not F.l and not F.c then local ae=""if aH then ae=ae..as..":"end;if F.n then ae=ae..aI..":"end;print(ae..au)end end end)if F.l and aJ then print(as)end;if F.c then print((aH and as..":"or"")..at)end end;local function aM(y,as,aH)local z,X=x(y)if not z then print("grep: "..as..": "..tostring(X))return end;aG(z,as,aH)end;local function aN(aO,aP)local h,_=pcall(syscall.listdir,aO)if not h then return end;for a0,a1 in ipairs(_)do local aQ=aO:gsub("/$","").."/"..a1;local aA=(aP~=""and aP.."/"or"")..a1;local v=syscall.type(aQ)if v=="directory"then aN(aQ,aA)elseif v=="file"then aM(aQ,aA,true)end end end;if#G==1 then aG(t(0),"(stdin)",false)else local aH=#G>2 or am;for k=2,#G do local y=m(G[k])local v=syscall.type(y)if v=="directory"then if am then aN(y,G[k])else print("grep: "..G[k]..": Is a directory")end elseif v then aM(y,G[k],aH)else print("grep: "..G[k]..": No such file or directory")end end end end;a6.sort=function(...)local F,G=B({...},"rnu")local S={}local function aR(N)local aS=R(N)for a0,T in ipairs(aS)do S[#S+1]=T end end;if#G==0 then aR(t(0))else for a0,ag in ipairs(G)do local z,X=x(m(ag))if not z then print("sort: "..ag..": "..tostring(X))else aR(z)end end end;table.sort(S,function(ag,ay)if F.n then local aT=tonumber(ag:match("^%-?%d+%.?%d*"))or 0;local aU=tonumber(ay:match("^%-?%d+%.?%d*"))or 0;return F.r and aT>aU or aTay or ag1 then return end;ae[#ae+1]=F.c and string.format("%7d %s",at,au)or au end;M(N,function(au)local aY=F.i and au:lower()or au;local aZ=F.i and(aV and aV:lower())or aV;if aY==aZ then aW=aW+1 else if aV~=nil then aX(aV,aW)end;aV=au;aW=1 end end)if aV~=nil then aX(aV,aW)end;if G[2]then local h,X=A(m(G[2]),table.concat(ae,"\n").."\n")if not h then print("uniq: "..G[2]..": "..tostring(X))end else for a0,T in ipairs(ae)do print(T)end end end;a6.tee=function(...)local F,G=B({...},"a")local a_=F.a and"a"or"w"local b0={}for a0,ag in ipairs(G)do local h,u=pcall(syscall.open,m(ag),a_)if not h then print("tee: "..ag..": "..tostring(u))else b0[#b0+1]=u end end;while true do local h,w=pcall(syscall.read,0,4096)if not h or not w or w==""then break end;pcall(syscall.write,1,w)for a0,u in ipairs(b0)do pcall(syscall.write,u,w)end end;for a0,u in ipairs(b0)do pcall(syscall.close,u)end end;a6.find=function(...)local ao={...}local b1,b2={},{}local b3,b4=nil,0;local k=1;while k<=#ao and ao[k]:sub(1,1)~="-"do b1[#b1+1]=ao[k]k=k+1 end;if#b1==0 then b1={"."}end;while k<=#ao do local b5=ao[k]if b5=="-name"then k=k+1;local aE="^"..(ao[k]or""):gsub("([%.%+%-%^%$%(%)%[%]%%])","%%%1"):gsub("%*",".*"):gsub("%?",".").."$"b2[#b2+1]=function(a0,a1,b6,b7)return a1:match(aE)~=nil end elseif b5=="-type"then k=k+1;local b8=ao[k]or""b2[#b2+1]=function(a0,a0,v,b6)if b8=="f"then return v=="file"elseif b8=="d"then return v=="directory"elseif b8=="l"then return v=="symlink"end;return true end elseif b5=="-maxdepth"then k=k+1;b3=tonumber(ao[k])or 0 elseif b5=="-mindepth"then k=k+1;b4=tonumber(ao[k])or 0 elseif b5=="-empty"then b2[#b2+1]=function(y,a0,v,b6)if v=="file"then local h,a3=pcall(syscall.stat,y)return h and a3 and(a3.size or 0)==0 elseif v=="directory"then local h,T=pcall(syscall.listdir,y)return h and T and#T==0 end;return false end end;k=k+1 end;local function b9(y,a1,v,ba)for a0,bb in ipairs(b2)do if not bb(y,a1,v,ba)then return false end end;return true end;local function bc(y,bd,ba)local v=syscall.type(y)if not v then return end;local a1=y:match("([^/]+)/?$")or y;if ba>=b4 and b9(y,a1,v,ba)then print(bd)end;if v=="directory"and(b3==nil or ba1 and n:sub(-1)=="/"do n=n:sub(1,-2)end;local ay=n:match("([^/]+)$")or n;if G[2]and ay:sub(-#G[2])==G[2]then ay=ay:sub(1,#ay-#G[2])end;print(ay)end;a6.dirname=function(...)local G={...}if#G==0 then print("dirname: missing operand")return end;for a0,n in ipairs(G)do while#n>1 and n:sub(-1)=="/"do n=n:sub(1,-2)end;local s=n:match("^(.*)/[^/]+$")if not s then print(".")elseif s==""then print("/")else print(s)end end end;a6.df=function(...)local F,a0=B({...},"h")local function bk(ac)local ah={"K","M","G","T"}local k=0;while ac>=1024 and k<#ah do ac=ac/1024;k=k+1 end;if k==0 then return tostring(math.floor(ac))end;if ac<10 then return string.format("%.1f%s",ac,ah[k])end;return math.floor(ac)..ah[k]end;local function az(ac)return F.h and bk(ac)or tostring(ac)end;print(string.format("%-20s %10s %10s %10s %6s %-s","Filesystem","Size","Used","Avail","Use%","Mounted on"))local bl={{"$","/"},{"devfs0000","/dev/"},{"tmpfs0000","/tmp/"}}for a0,aL in ipairs(bl)do local bm,bn=aL[1],aL[2]print(string.format("%-20s %10s %10s %10s %6s %-s",bm,"?","?","?","?%",bn))end end;local function bo(aO,aP)local h,bp=pcall(syscall.listdir,aO)if not h or not bp then return{}end;local aj={}for a0,a1 in ipairs(bp)do if aP==""or a1:sub(1,#aP)==aP then local bq=(aO=="/"and"/"or aO.."/")..a1;local v=syscall.type(bq)aj[#aj+1]=v=="directory"and a1 .."/"or a1 end end;table.sort(aj)return aj end;local function br(aP)local aj={}local bs={}for bt in pairs(a6)do if aP==""or bt:sub(1,#aP)==aP then if not bs[bt]then aj[#aj+1]=bt;bs[bt]=true end end end;local bu=string.split(syscall.getEnviron("PATH")or"/bin/",":")for a0,n in ipairs(bu)do local h,bp=pcall(syscall.listdir,n)if h and bp then for a0,a1 in ipairs(bp)do local bq=(n:sub(-1)=="/"and n or n.."/")..a1;local bv=pcall(syscall.access,bq,"x")if bv and(aP==""or a1:sub(1,#aP)==aP)then if not bs[a1]then aj[#aj+1]=a1;bs[a1]=true end end end end end;table.sort(aj)return aj end;local function bw(_)if#_==0 then return""end;local bx=_[1]for k=2,#_ do local a3=_[k]local I=1;while I<=#bx and I<=#a3 and bx:sub(I,I)==a3:sub(I,I)do I=I+1 end;bx=bx:sub(1,I-1)if bx==""then return""end end;return bx end;local function by(bz)syscall.write(1,"\n")local bA=51;local bB=0;for a0,L in ipairs(bz)do if#L>bB then bB=#L end end;local bC=bB+2;local bD=math.max(1,math.floor(bA/bC))local k=0;for a0,L in ipairs(bz)do local bE=L..string.rep(" ",bC-#L)syscall.write(1,bE)k=k+1;if k%bD==0 then syscall.write(1,"\n")end end;if k%bD~=0 then syscall.write(1,"\n")end end;local function bF(bG,bH)local bI=bG:sub(1,bH-1)local bJ={}for b5 in bI:gmatch("%S+")do bJ[#bJ+1]=b5 end;local bK=bI:match("%S+$")or""local bL=#bJ==0 or bI:sub(-1)~=" "and#bJ==1;local bM,bN;if bK:find("/")then bM=bK:match("^(.*/)")or"/"bN=bK:match("[^/]*$")or""else bM=nil;bN=bK end;return bJ,bK,bL,bM,bN end;local bO={last=nil,idx=0,list={}}local function bP(bG,bH)local bJ,bK,bL,bM,bN=bF(bG,bH)local bQ;if bL then if bM then local aO=bM:sub(1,1)=="/"and bM or syscall.getcwd().."/"..bM;bQ=bo(aO,bN)for k,L in ipairs(bQ)do bQ[k]=bM..L end else bQ=br(bN)end else local aO,bR;if bM then aO=bM:sub(1,1)=="/"and bM or syscall.getcwd().."/"..bM;bR=bN else aO=syscall.getcwd()bR=bN end;bQ=bo(aO,bR)if bM then for k,L in ipairs(bQ)do bQ[k]=bM..L end end end;if#bQ==0 then return bG,bH,false end;local bS=bG.."\0"..tostring(bH)if bO.last~=bS then bO.last=bS;bO.idx=0;bO.list=bQ end;if#bQ==1 then local bT=bQ[1]local bU=bG:sub(1,bH-1-#bK)local bV=bG:sub(bH)local bW=bU..bT..bV;local bX=#bU+#bT+1;bO.last=nil;return bW,bX,true end;local bx=bw(bQ)if#bx>#bK then local bU=bG:sub(1,bH-1-#bK)local bV=bG:sub(bH)local bW=bU..bx..bV;local bX=#bU+#bx+1;bO.last=bW.."\0"..tostring(bX)bO.list=bQ;return bW,bX,true else by(bQ)return bG,bH,true end end;local function bY()syscall.devctl(1,"sfgc",0x00FF00)syscall.write(1,d)syscall.devctl(1,"sfgc",0xFFFFFF)syscall.write(1,":")syscall.devctl(1,"sfgc",0x24FFFF)syscall.write(1,syscall.getcwd())syscall.devctl(1,"sfgc",0xFFFFFF)syscall.write(1,"$ ")local bZ=syscall.devctl(1,"gpos")local b_=tonumber(bZ:sub(1,bZ:find(";")-1))local c0=tonumber(bZ:sub(bZ:find(";")+1))local bG=""local c1=false;local bH=1;local c2=0;local c3=true;local function c4()if#bG==0 then return""end;local a0,bK,bL,bM,bN=bF(bG,bH)if bH~=#bG+1 then return""end;local bQ;if bL then if bM then local aO=bM:sub(1,1)=="/"and bM or syscall.getcwd().."/"..bM;bQ=bo(aO,bN)for k,L in ipairs(bQ)do bQ[k]=bM..L end else bQ=br(bN)end else local aO,bR;if bM then aO=bM:sub(1,1)=="/"and bM or syscall.getcwd().."/"..bM;bR=bN else aO=syscall.getcwd()bR=bN end;bQ=bo(aO,bR)if bM then for k,L in ipairs(bQ)do bQ[k]=bM..L end end end;if#bQ==0 then return""end;local bx=bw(bQ)if#bx>#bK then return bx:sub(#bK+1)end;return""end;local function c5()syscall.devctl(1,"spos",b_,c0)syscall.write(1,string.sub(bG,1,bH-1))if c1 then syscall.devctl(1,"sfgc",0x000000)syscall.devctl(1,"sbgc",0xFFFFFF)end;if bH>#bG then syscall.write(1," ")else syscall.write(1,string.sub(bG,bH,bH))end;syscall.devctl(1,"sfgc",0xFFFFFF)syscall.devctl(1,"sbgc",0x000000)local bV=string.sub(bG,bH+1)syscall.write(1,bV)local c6=c4()if#c6>0 then syscall.devctl(1,"sfgc",0x6D00FF)syscall.write(1,c6)syscall.devctl(1,"sfgc",0xFFFFFF)syscall.write(1," ")else syscall.write(1," ")end end;while true do local c7=syscall.read(0)if c7 and c7~=""then if c7==""then if bH>1 then bH=bH-1;c3=true end elseif c7==""then if bH<=#bG then bH=bH+1;c3=true end elseif c7==""then if c2<#e then c2=c2+1;bG=e[#e-c2+1]bH=#bG+1;c3=true end elseif c7==""then if c2>1 then c2=c2-1;bG=e[#e-c2+1]bH=#bG+1;c3=true elseif c2==1 then c2=0;bG=""bH=1;c3=true end elseif c7==""then bH=1;c3=true elseif c7==""then bH=#bG+1;c3=true elseif c7=="[3~"then if bH<=#bG then bG=string.sub(bG,1,bH-1)..string.sub(bG,bH+1)c3=true end elseif c7=="\t"then local bW,bX,c8=bP(bG,bH)if c8 then bG=bW;bH=bX;local c9=syscall.devctl(1,"gpos")local ca=c9:find(";")local cb=tonumber(c9:sub(1,ca-1))local cc=tonumber(c9:sub(ca+1))if cb>1 then syscall.devctl(1,"spos",1,cc)local cd=syscall.devctl(1,"size")or"51;19"local aC=tonumber(cd:match("^(%d+)"))or 51;syscall.write(1,string.rep(" ",aC))syscall.devctl(1,"spos",1,cc)end;syscall.devctl(1,"sfgc",0x00FF00)syscall.write(1,d)syscall.devctl(1,"sfgc",0xFFFFFF)syscall.write(1,":")syscall.devctl(1,"sfgc",0x00FFFF)syscall.write(1,syscall.getcwd())syscall.devctl(1,"sfgc",0xFFFFFF)syscall.write(1,"$ ")c9=syscall.devctl(1,"gpos")ca=c9:find(";")b_=tonumber(c9:sub(1,ca-1))c0=tonumber(c9:sub(ca+1))c3=true end elseif c7=="\b"then if bH>1 then bG=string.sub(bG,1,bH-2)..string.sub(bG,bH)bH=bH-1;c3=true end elseif c7=="\n"then syscall.devctl(1,"sfgc",0xFFFFFF)syscall.devctl(1,"sbgc",0x000000)syscall.devctl(1,"spos",b_,c0)syscall.write(1,bG.." \n")return bG elseif#c7==1 and c7:byte(1)>=32 and c7:byte(1)<127 then bG=string.sub(bG,1,bH-1)..c7 ..string.sub(bG,bH)bH=bH+1;c3=true end end;local ce=math.floor(syscall.getUptime()/500)%2==0;if ce~=c1 then c1=ce;c3=true end;if c3 then c5()c3=false end end end;local function cf(cg,ch)syscall.devctl(1,"sfgc",0xFF0000)local a3=tostring(ch)local au,ci=a3:match("%]:(%d+): (.+)$")if not au then au,ci=a3:match(":(%d+): (.+)$")end;if au then printInline(cg..": error on line "..au..": ")print(ci)else print(cg..": "..a3)end;syscall.devctl(1,"sfgc",0xFFFFFF)end;local function cj(ck)do local cl=load("return "..ck,"@equation","t",{})if cl then local h,cm=pcall(cl)if h and type(cm)=="number"then print(cm)return end end end;f=false;local G=string.split(ck," ")for k=#G,1,-1 do if G[k]==""then table.remove(G,k)end end;if#G==0 then return end;if a6[G[1]]then local h,X=pcall(a6[G[1]],table.unpack(G,2))if not h then cf(G[1],X)end;return end;local cn=""if string.find(G[1],"/")then local co=G[1]if co:sub(1,1)~="/"then co=syscall.getcwd().."/"..co end;if c.exists(co)then cn=co end else local bu=string.split(syscall.getEnviron("PATH"),":")for a0,n in pairs(bu)do if c.exists(n..G[1])then cn=n..G[1]break end end;if cn==""then local a7=syscall.getcwd()local co=a7 ..(a7:sub(-1)=="/"and""or"/")..G[1]if c.exists(co)then cn=co end end end;if cn==""then print(G[1]..": Command not found")return end;local cg=cn:match("([^/]+)$")or G[1]local bv,cp=pcall(syscall.access,cn,"x")if not bv then syscall.devctl(1,"sfgc",0xFF0000)print(cg..": Permission denied")syscall.devctl(1,"sfgc",0xFFFFFF)return end;local cq=syscall.spawn(function()syscall.open("/dev/tty/1","r")syscall.open("/dev/tty/1","w")syscall.open("/dev/null","w")syscall.exec(cn,{table.unpack(G,2)})end,cg)while true do local cr,ab=syscall.collect(cq)if cr then if ab then print("\nTask exited with code:\n"..tostring(ab))end;return end;if f then local a4=syscall.kill(cq)if a4 then syscall.devctl(1,"sbgc",16)syscall.devctl(1,"sfgc",0xFF0000)print("\nProgram Terminated.")syscall.devctl(1,"sfgc",0xFFFFFF)end;f=false;break end;sleep(0.05)end end;while true do local ck=bY()if ck~=""then if ck~=e[#e]then table.insert(e,ck)end;cj(ck)end end end,debug.traceback)if not a then syscall.log("Error running shell: "..b,"ERROR")syscall.devctl(1,"sfgc",0xFF0000)syscall.devctl(1,"sbgc",0x000000)print()print("Error running shell: ")print(b)end diff --git a/prod/hysh/bin/id b/prod/hysh/bin/id deleted file mode 100644 index 6016ae6..0000000 --- a/prod/hysh/bin/id +++ /dev/null @@ -1 +0,0 @@ -local a={...}local b;if a[1]then b=syscall.getuid(a[1])if not b then print("id: user '"..a[1].."' does not exist")syscall.exit(1)return end else b=syscall.getuid()end;local c=syscall.getpasswd(b)local d=c and c.username or tostring(b)local e=c and c.gid or b;print(string.format("uid=%d(%s) gid=%d(%s)",b,d,e,d)) diff --git a/prod/hysh/bin/ll b/prod/hysh/bin/ll deleted file mode 100644 index 5cefbfd..0000000 --- a/prod/hysh/bin/ll +++ /dev/null @@ -1,3 +0,0 @@ -local args={...} -table.insert(args, "-lah") -syscall.exec("/bin/ls", args) \ No newline at end of file diff --git a/prod/hysh/bin/ln b/prod/hysh/bin/ln deleted file mode 100644 index 1e64e42..0000000 --- a/prod/hysh/bin/ln +++ /dev/null @@ -1 +0,0 @@ -local a=syscall.getTask(syscall.getpid()).name;local b={s=false,f=false,help=false}local c={}for d,e in ipairs({...})do if e:sub(1,2)=="--"then local f=e:sub(3)if b[f]==nil then print(a..": unrecognized option '"..e.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;b[f]=true elseif e:sub(1,1)=="-"then for g=2,#e do local f=e:sub(g,g)if b[f]==nil then print(a..": invalid option '-"..f.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;b[f]=true end else table.insert(c,e)end end;if b.help then print("Usage: "..a.." [OPTION]... TARGET LINK_NAME")print(" "..a.." [OPTION]... TARGET... DIRECTORY")print("Create links between files.")print("")print("Options:")print(" -s make symbolic links instead of hard links")print(" -f remove existing destination files")print(" --help display this help and exit")print("")print("With no -s, hard links are not supported (filesystem limitation).")print("Use -s for symbolic links.")return end;if#c<2 then print(a..": missing operand")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;if not b.s then print(a..": hard links are not supported; use -s for symbolic links")syscall.exit(1)return end;local h=c[#c]local i=syscall.type(h)=="directory"local function j()local k=syscall.getcwd()if k:sub(-1)~="/"then k=k.."/"end;return k end;local function l(m)if m:sub(1,1)~="/"then m=j()..m end;return m end;for g=1,#c-1 do local n=c[g]local o;if i then local p=n:match("[^/]+$")or n;o=l(h)if o:sub(-1)~="/"then o=o.."/"end;o=o..p else o=l(h)end;if b.f and syscall.exists(o)then local q,r=pcall(syscall.remove,o)if not q then print(a..": cannot remove '"..o.."': "..tostring(r))syscall.exit(1)return end end;local q,r=pcall(syscall.symlink,n,o)if not q then print(a..": failed to create symlink '"..o.."' -> '"..n.."': "..tostring(r))syscall.exit(1)return end end diff --git a/prod/hysh/bin/login b/prod/hysh/bin/login deleted file mode 100644 index cdcb3b1..0000000 --- a/prod/hysh/bin/login +++ /dev/null @@ -1 +0,0 @@ -syscall.open("/dev/tty/1","r")syscall.open("/dev/tty/1","w")syscall.open("/dev/null","w")local a=3;local function b(c)local d=""while true do local e=syscall.read(0)if not e or e==""then elseif e=="\n"then syscall.write(1,"\n")return d elseif e=="\b"then if#d>0 then d=d:sub(1,-2)syscall.write(1,"\b \b")end else d=d..e;syscall.write(1,c or e)end end end;local function f()local g=""local h,i=pcall(function()local j=syscall.open("/etc/shadow","r")g=syscall.read(j,65535)or""syscall.close(j)end)if g:match("%S")then return end;syscall.devctl(1,"clear")syscall.devctl(1,"spos",1,1)syscall.devctl(1,"sfgc",0x00FF00)syscall.write(1,"HyperionOS First Boot Setup\n")syscall.devctl(1,"sfgc",0xFFFFFF)syscall.write(1,"No root password is set. Please create one now.\n\n")while true do syscall.write(1,"New root password: ")local k=b("*")syscall.write(1,"Confirm password: ")local l=b("*")if k~=l then syscall.devctl(1,"sfgc",0xFF0000)syscall.write(1,"Passwords do not match. Try again.\n\n")syscall.devctl(1,"sfgc",0xFFFFFF)elseif#k<6 then syscall.devctl(1,"sfgc",0xFF0000)syscall.write(1,"Password too short (minimum 6 characters).\n\n")syscall.devctl(1,"sfgc",0xFFFFFF)else local m,n=syscall.setpassword(0,k)if m then syscall.devctl(1,"sfgc",0x00FF00)syscall.write(1,"Root password set.\n\n")syscall.devctl(1,"sfgc",0xFFFFFF)sleep(0.5)break else syscall.devctl(1,"sfgc",0xFF0000)syscall.write(1,"Error: "..tostring(n).."\n")syscall.devctl(1,"sfgc",0xFFFFFF)end end end end;local function o(p,q,r,s)local t,u=pcall(syscall.exists,r)if not t or not u then syscall.write(1,"login: shell not found: "..r.."\n")sleep(2)return false end;local v,w=pcall(syscall.access,r,"rx")syscall.setEnviron("HOME",s)syscall.setEnviron("USER",p)syscall.setEnviron("SHELL",r)syscall.setEnviron("PATH","/bin/")local x,y=pcall(syscall.setuid,q)if not x then syscall.write(1,"login: setuid failed: "..tostring(y).."\n")sleep(2)return false end;local z,A=pcall(syscall.chdir,s)if not z then pcall(syscall.chdir,"/")end;local m,n=pcall(syscall.execspawn,r,p..":shell")if not m then syscall.write(1,"login: failed to launch shell: "..tostring(n).."\n")sleep(2)return false end;syscall.exit(0)end;local function B()syscall.devctl(1,"clear")syscall.devctl(1,"sfgc",0xFFFFFF)syscall.devctl(1,"sbgc",0x000000)syscall.devctl(1,"spos",1,1)local C=syscall.getHostname()or"hyperion"syscall.write(1,"HyperionOS\n")syscall.write(1,C.." login\n\n")local D=0;while D ")print(" "..a.." -x ")print("")print("Pack a directory into a portable HFS image file, or extract one.")print("")print(" recursively pack srcdir into image.hfs")print(" -x extract image.hfs into dest (created if needed)")print("")print("HFS images can be mounted with:")print(" mount -o loop /path/to/image.hfs /mnt/point")print("")print("Requires root.")return end;local i=require("fs")if c.x then if#b<2 then print(a..": -x requires and ")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;local j=b[1]local k=b[2]if j:sub(1,1)~="/"then j=syscall.getcwd().."/"..j end;if k:sub(1,1)~="/"then k=syscall.getcwd().."/"..k end;local l="/tmp/._loimgcreate_"..tostring(math.random(100000,999999))local m,n=pcall(syscall.losetup,j,true)if not m then print(a..": losetup: "..tostring(n))syscall.exit(1)return end;local o,p=pcall(syscall.mount,l,n)if not o then pcall(syscall.lodetach,n)print(a..": mount: "..tostring(p))syscall.exit(1)return end;if not i.isDir(k)then local q,r=pcall(syscall.mkdir,k)if not q then pcall(syscall.umount,l)pcall(syscall.lodetach,n)print(a..": mkdir '"..b[2].."': "..tostring(r))syscall.exit(1)return end end;local s=0;local function t(u,v)local w=i.list(u)if not w then return end;for d,x in ipairs(w)do local y=u:gsub("/$","").."/"..x;local z=v:gsub("/$","").."/"..x;if i.isDir(y)then pcall(syscall.mkdir,z)t(y,z)else local A,B=pcall(syscall.open,y,"r")if A then local o,C=pcall(syscall.open,z,"w")if o then local q,D=pcall(syscall.read,B,65536*16)if q and D then pcall(syscall.write,C,D)end;pcall(syscall.close,C)s=s+1 end;pcall(syscall.close,B)end end end end;t(l,k)pcall(syscall.umount,l)pcall(syscall.lodetach,n)syscall.devctl(1,"sfgc",0x00FFFF)print(a..": extracted "..s.." file(s) to "..k)syscall.devctl(1,"sfgc",0xFFFFFF)return end;if#b<2 then print(a..": missing operands — need and ")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;local E=b[1]local j=b[2]if E:sub(1,1)~="/"then E=syscall.getcwd().."/"..E end;if j:sub(1,1)~="/"then j=syscall.getcwd().."/"..j end;if not i.isDir(E)then print(a..": '"..b[1].."': not a directory")syscall.exit(1)return end;local A,F=pcall(syscall.loimgcreate,E)if not A then local G=tostring(F)if G:find("EPERM")then G="Permission denied"elseif G:find("ENOTDIR")then G="'"..b[1].."': not a directory"end;print(a..": "..G)syscall.exit(1)return end;local o,H=pcall(syscall.loimgwrite,F,j)if not o then print(a..": write '"..b[2].."': "..tostring(H))syscall.exit(1)return end;local I=0;for d in F:gmatch("\n")do I=I+1 end;local J=#F;syscall.devctl(1,"sfgc",0x00FFFF)print(a..": image written to "..j)syscall.devctl(1,"sfgc",0x6D00FF)print(string.format(" %d records, %d bytes",I-1,J))syscall.devctl(1,"sfgc",0xFFFFFF) diff --git a/prod/hysh/bin/losetup b/prod/hysh/bin/losetup deleted file mode 100644 index 393988c..0000000 --- a/prod/hysh/bin/losetup +++ /dev/null @@ -1 +0,0 @@ -local a=syscall.getTask(syscall.getpid()).name;local b,c={},{d=false,l=false,i=false,help=false}for d,e in ipairs({...})do if e:sub(1,2)=="--"then local f=e:sub(3)if f=="help"then c.help=true else print(a..": unrecognised option '"..e.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end elseif e:sub(1,1)=="-"then for g=2,#e do local h=e:sub(g,g)if c[h]~=nil then c[h]=true else print(a..": invalid option '-"..h.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end end else table.insert(b,e)end end;if c.help then print("Usage: "..a.." ")print(" "..a.." -i ")print(" "..a.." -d ")print(" "..a.." -l")print("")print("Manage loop devices.")print("")print(" attach a directory (bind) or .hfs image file")print(" -i force image mode for the given file")print(" -d detach loop device by id (must be unmounted first)")print(" -l list all currently attached loop devices")print("")print("Requires root. Loop device ids look like loop0, loop1, …")return end;if c.l then local i,j=pcall(syscall.lolist)if not i then print(a..": "..tostring(j))syscall.exit(1)return end;local k=false;local l={}for m in pairs(j)do l[#l+1]=m end;table.sort(l)for d,m in ipairs(l)do k=true;local n=j[m]local o=type(n)=="table"and n.mode or"bind"local p=type(n)=="table"and n.path or tostring(n)local q=o=="image"and 0x00FFFF or 0x0000FF;syscall.devctl(1,"sfgc",0x00FF00)printInline(string.format("%-10s",m))syscall.devctl(1,"sfgc",q)printInline(string.format("%-7s","["..o.."]"))syscall.devctl(1,"sfgc",0xFFFFFF)print(" "..p)end;if not k then syscall.devctl(1,"sfgc",0x6D00FF)print(a..": no loop devices attached")syscall.devctl(1,"sfgc",0xFFFFFF)end;return end;if c.d then if#b<1 then print(a..": -d requires a loop device id")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;local m=b[1]local i,r=pcall(syscall.lodetach,m)if not i then local s=tostring(r)if s:find("EPERM")then s="Permission denied"elseif s:find("ENXIO")then s="no such loop device '"..m.."'"elseif s:find("EBUSY")then s="device '"..m.."' is still mounted, unmount first"end;print(a..": "..s)syscall.exit(1)return end;syscall.devctl(1,"sfgc",0x00FFFF)print(a..": detached "..m)syscall.devctl(1,"sfgc",0xFFFFFF)return end;if#b<1 then print(a..": missing path operand")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;local p=b[1]if p:sub(1,1)~="/"then p=syscall.getcwd().."/"..p end;local t=syscall.type and syscall.type(p)if not(t=="file"or t=="directory")then print(a..": '"..b[1].."': no such file or directory")syscall.exit(1)return end;local i,u=pcall(syscall.losetup,p,c.i or nil)if not i then local s=tostring(u)if s:find("EPERM")then s="Permission denied"elseif s:find("ENOENT")then s="'"..b[1].."': no such file"elseif s:find("EINVAL")then s="'"..b[1].."': not a directory or .hfs image"elseif s:find("EIO")then s="'"..b[1].."': I/O error reading image"end;print(a..": "..s)syscall.exit(1)return end;print(u) diff --git a/prod/hysh/bin/ls b/prod/hysh/bin/ls deleted file mode 100644 index 1972c42..0000000 --- a/prod/hysh/bin/ls +++ /dev/null @@ -1 +0,0 @@ -local a={a=false,h=false,l=false,help=false}local b={...}local c={}local d=syscall.getTask(syscall.getpid()).name;for e,f in pairs(b)do if f:sub(1,2)=="--"then local g=f:sub(3)if a[g]==nil then print(d..": unrecognized option '"..f.."'.")print("try '"..d.." --help' for more information.")return end;a[g]=true elseif f:sub(1,1)=="-"then for h=2,#f do local g=f:sub(h,h)if a[g]==nil then print(d..": invalid option '-"..g.."'.")print("try '"..d.." --help' for more information.")return end;a[g]=true end else table.insert(c,f)end end;if a.help then print("Usage: "..d.." [OPTION]... [DIR]")print("List all entries in the specified DIRectory, or cwd if not specified.")print("")print("Options:")print(" -a do not ignore entries starting with .")print(" -h with -l, print sizes in human readable format")print(" -l use a long listing format")print(" --help display this help and exit")return end;local i=require("fs")local j=c[1]or""if j:sub(1,1)~="/"then j=syscall.getcwd().."/"..j end;if j:sub(-1)~="/"then j=j.."/"end;if not i.isDir(j)then print(d..": cannot access '"..(c[1]or j).."': no such directory")return end;local function k(l,m)local function n(o)return math.floor(l/2^o)%2==1 end;local p;if m==0x01 then p="l"elseif m==nil then p="-"else p="-"end;local q=n(5)and"r"or"-"local r=n(4)and"w"or"-"local s=n(9)and(n(6)and"s"or"x")or(n(6)and"S"or"-")local t=n(3)and"r"or"-"local u=n(2)and"w"or"-"local v=n(8)and"x"or"-"local w=n(1)and"r"or"-"local x=n(0)and"w"or"-"local y=n(7)and"x"or"-"return p..q..r..s..t..u..v..w..x..y end;local z={"K","M","G","T"}local function A(B)local C=0;while B>=1024 and C<#z do B=B/1024;C=C+1 end;if C==0 then return tostring(B).."B"end;if B<10 then return string.format("%.1f%s",B,z[C])end;return math.floor(B)..z[C]end;local D=syscall.devctl(1,"size")local E=tonumber(D:match("^(%d+)"))or 80;local F=i.list(j)if not a.a then for h=#F,1,-1 do if F[h]:sub(1,1)=="."then table.remove(F,h)end end end;table.sort(F)if#F==0 then return end;if a.l then for e,f in ipairs(F)do local G=j..f;local H=syscall.lstat and syscall.lstat(G)or syscall.stat(G)local I=i.isDir(G)local J=H and H.etype==0x01;local isSock=H and H.etype==0x02;local K;if J then K="l"elseif I then K="d"elseif isSock then K="s"else K="-"end;local L;if H and H.perms then L=k(H.perms,H.etype)else L=K.."---------"end;local B=H and H.size or 0;local M=a.h and A(B)or tostring(B)local N=H and H.modified and math.floor(H.modified/1000)or 0;local O=H and tostring(H.owner)or"0"local P=H and tostring(H.group)or"0"printInline(L.." "..O.." "..P.." ")printInline(string.format("%6s",M).." ")printInline(tostring(N).." ")if J then syscall.devctl(1,"sfgc",0x00FFFF)printInline(f)syscall.devctl(1,"sfgc",0xFFFFFF)local Q,R=pcall(syscall.readlink,G)if Q then printInline(" -> ")local S=pcall(syscall.stat,G)syscall.devctl(1,"sfgc",S and 0x00FFFF or 0xFF0000)printInline(R)syscall.devctl(1,"sfgc",0xFFFFFF)end elseif I then syscall.devctl(1,"sfgc",0x6D00FF)printInline(f)syscall.devctl(1,"sfgc",0xFFFFFF)elseif isSock then syscall.devctl(1,"sfgc",0xFF00FF)printInline(f)syscall.devctl(1,"sfgc",0xFFFFFF)else local T=H and H.perms and math.floor(H.perms/2^9)%2==1;syscall.devctl(1,"sfgc",T and 0x00FF00 or 0xFFFFFF)printInline(f)syscall.devctl(1,"sfgc",0xFFFFFF)end;print("")end;return end;local U=0;for e,f in ipairs(F)do if#f+2>U then U=#f+2 end end;local V=math.max(1,math.floor(E/U))for h,f in ipairs(F)do local G=j..f;local I=i.isDir(G)local H=syscall.lstat and syscall.lstat(G)or syscall.stat(G)local J=H and H.etype==0x01;if J then syscall.devctl(1,"sfgc",0x00FFFF)elseif I then syscall.devctl(1,"sfgc",0x6D00FF)elseif isSock then syscall.devctl(1,"sfgc",0xFF00FF)else local T=H and H.perms and math.floor(H.perms/2^9)%2==1;syscall.devctl(1,"sfgc",T and 0x00FF00 or 0xFFFFFF)end;printInline(f)syscall.devctl(1,"sfgc",0xFFFFFF)printInline((" "):rep(U-#f))if h%V==0 then print("")end end;if#F%V~=0 then print("")end diff --git a/prod/hysh/bin/lsusers b/prod/hysh/bin/lsusers deleted file mode 100644 index 6a5fa28..0000000 --- a/prod/hysh/bin/lsusers +++ /dev/null @@ -1 +0,0 @@ -local a=syscall.listusers()if not a or#a==0 then print("No users found.")return end;syscall.devctl(1,"sfgc",0xDBDBDB)print(string.format("%-6s %-6s %-16s %-20s %s","UID","GID","Username","Home","Shell"))print(string.rep("-",65))syscall.devctl(1,"sfgc",0xFFFFFF)for b,c in ipairs(a)do local d=c.locked and" [locked]"or""if c.locked then syscall.devctl(1,"sfgc",0xFF0000)end;print(string.format("%-6d %-6d %-16s %-20s %s%s",c.uid,c.gid,c.username,c.homedir,c.shell,d))if c.locked then syscall.devctl(1,"sfgc",0xFFFFFF)end end diff --git a/prod/hysh/bin/mount b/prod/hysh/bin/mount deleted file mode 100644 index d73e0f0..0000000 --- a/prod/hysh/bin/mount +++ /dev/null @@ -1 +0,0 @@ -local a=syscall.getTask(syscall.getpid()).name;local b,c={},{help=false,o=nil}local d=1;local e={...}while d<=#e do local f=e[d]if f:sub(1,2)=="--"then local g=f:sub(3)if g=="help"then c.help=true else print(a..": unrecognised option '"..f.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end elseif f=="-o"then d=d+1;c.o=e[d]elseif f:sub(1,1)=="-"then local h=f:sub(2)if h:sub(1,1)=="o"then if#h>1 then c.o=h:sub(2)else d=d+1;c.o=e[d]end else print(a..": invalid option '"..f.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end else table.insert(b,f)end;d=d+1 end;if c.help then print("Usage: "..a)print(" "..a.." ")print(" "..a.." -o loop ")print("")print("Mount a loop device or filesystem.")print("")print(" (no args) list all active mount points")print(" mount an already-attached loop device")print(" -o loop attach src as loop device and mount at dest")print(" src can be a directory (bind) or .hfs image")print("")print("Requires root for all operations except listing.")return end;if#b==0 and not c.o then local i,j=pcall(syscall.mounts or function()error("ENOSYS")end)local k={}local l,m=pcall(syscall.lolist)if l then for n,o in pairs(m)do local p=type(o)=="table"and o.path or tostring(o)local q=type(o)=="table"and o.mode or"bind"k[n]={path=p,mode=q}end end;if next(k)==nil then syscall.devctl(1,"sfgc",0xFF00FF)print("(no loop devices attached)")syscall.devctl(1,"sfgc",0xFFFFFF)return end;for n,o in pairs(k)do local r=o.mode=="image"and 0x00FFFF or 0x0000FF;syscall.devctl(1,"sfgc",r)printInline(o.mode.." "..n)syscall.devctl(1,"sfgc",0xFFFFFF)print(" on "..o.path)end;return end;if c.o and c.o:lower()=="loop"then if#b<2 then print(a..": -o loop requires and ")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;local s=b[1]local t=b[2]if s:sub(1,1)~="/"then s=syscall.getcwd().."/"..s end;if t:sub(1,1)~="/"then t=syscall.getcwd().."/"..t end;local i,u=pcall(syscall.losetup,s)if not i then local v=tostring(u)if v:find("EPERM")then v="Permission denied"elseif v:find("EINVAL")then v="'"..b[1].."': not a directory or .hfs image"elseif v:find("EIO")then v="'"..b[1].."': I/O error reading image"end;print(a..": losetup: "..v)syscall.exit(1)return end;local w,x=pcall(syscall.mount,t,u)if not w then pcall(syscall.lodetach,u)local v=tostring(x)if v:find("EPERM")then v="Permission denied"elseif v:find("EBUSY")then v="'"..t.."' is already a mount point"elseif v:find("ENODEV")then v="loop device not found (internal error)"end;print(a..": mount: "..v)syscall.exit(1)return end;syscall.devctl(1,"sfgc",0x00FFFF)print(a..": "..u.." mounted at "..t)syscall.devctl(1,"sfgc",0xFFFFFF)return end;if#b==2 then local u=b[1]local t=b[2]if t:sub(1,1)~="/"then t=syscall.getcwd().."/"..t end;local i,y=pcall(syscall.mount,t,u)if not i then local v=tostring(y)if v:find("EPERM")then v="Permission denied"elseif v:find("ENODEV")then v="'"..u.."': no such device - use losetup first"elseif v:find("EBUSY")then v="'"..t.."' is already a mount point"elseif v:find("EINVAL")then v="invalid arguments"end;print(a..": "..v)syscall.exit(1)return end;syscall.devctl(1,"sfgc",0x00FFFF)print(a..": "..u.." mounted at "..t)syscall.devctl(1,"sfgc",0xFFFFFF)return end;print(a..": wrong number of arguments")print("try '"..a.." --help' for more information.")syscall.exit(1) diff --git a/prod/hysh/bin/passwd b/prod/hysh/bin/passwd deleted file mode 100644 index f7b3e2b..0000000 --- a/prod/hysh/bin/passwd +++ /dev/null @@ -1 +0,0 @@ -local a={...}local b=a[1]local c=syscall.getuid()local d;if b then d=syscall.getuid()if not d then print("passwd: user '"..b.."' does not exist")syscall.exit(1)return end;if c~=0 and d~=c then print("passwd: permission denied")syscall.exit(1)return end else d=c;b=syscall.getUsername(c)or tostring(c)end;if c~=0 then printInline("Current password: ")local e=""while true do local f=syscall.read(0)if not f or f==""then elseif f=="\n"then syscall.write(1,"\n")break elseif f=="\b"then if#e>0 then e=e:sub(1,-2)syscall.write(1,"\b \b")end else e=e..f;syscall.write(1,"*")end end;local g,h=syscall.login(d,e)if not g then sleep(1)print("passwd: authentication failure")syscall.exit(1)return end end;printInline("New password: ")local i=""while true do local f=syscall.read(0)if not f or f==""then elseif f=="\n"then syscall.write(1,"\n")break elseif f=="\b"then if#i>0 then i=i:sub(1,-2)syscall.write(1,"\b \b")end else i=i..f;syscall.write(1,"*")end end;printInline("Confirm password: ")local j=""while true do local f=syscall.read(0)if not f or f==""then elseif f=="\n"then syscall.write(1,"\n")break elseif f=="\b"then if#j>0 then j=j:sub(1,-2)syscall.write(1,"\b \b")end else j=j..f;syscall.write(1,"*")end end;if i~=j then print("passwd: passwords do not match")syscall.exit(1)return end;local g,h=syscall.setpassword(d,i)if not g then print("passwd: "..tostring(h))syscall.exit(1)return end;print("passwd: password updated for '"..b.."'") diff --git a/prod/hysh/bin/ps b/prod/hysh/bin/ps deleted file mode 100644 index 11d9cc3..0000000 --- a/prod/hysh/bin/ps +++ /dev/null @@ -1 +0,0 @@ -for a,b in ipairs(syscall.getTasks())do local c=syscall.getTask(b)print(c.pid,c.username,c.name,c.status)end diff --git a/prod/hysh/bin/readlink b/prod/hysh/bin/readlink deleted file mode 100644 index 52522cc..0000000 --- a/prod/hysh/bin/readlink +++ /dev/null @@ -1 +0,0 @@ -local a=syscall.getTask(syscall.getpid()).name;local b={n=false,f=false,e=false,help=false}local c={}for d,e in ipairs({...})do if e:sub(1,2)=="--"then local f=e:sub(3)if b[f]==nil then print(a..": unrecognized option '"..e.."'")syscall.exit(1)return end;b[f]=true elseif e:sub(1,1)=="-"then for g=2,#e do local f=e:sub(g,g)if b[f]==nil then print(a..": invalid option '-"..f.."'")syscall.exit(1)return end;b[f]=true end else table.insert(c,e)end end;if b.help then print("Usage: "..a.." [OPTION]... FILE...")print("Print the resolved target of symbolic links.")print("")print("Options:")print(" -f canonicalize: follow every symlink; last component need not exist")print(" -e like -f but all components must exist")print(" -n do not output trailing newline")print(" --help display this help and exit")return end;if#c==0 then print(a..": missing operand")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;local function h(i)if i:sub(1,1)~="/"then local j=syscall.getcwd()if j:sub(-1)~="/"then j=j.."/"end;i=j..i end;return i end;local k=false;for d,l in ipairs(c)do l=h(l)if b.f or b.e then local m,n=pcall(syscall.stat,l)if not m then if b.e then print(a..": "..l..": "..tostring(n))k=true else if not b.n then print(l)else printInline(l)end end else if not b.n then print(l)else printInline(l)end end else local m,o=pcall(syscall.readlink,l)if not m then print(a..": "..l..": "..tostring(o))k=true else if not b.n then print(o)else printInline(o)end end end end;if k then syscall.exit(1)end diff --git a/prod/hysh/bin/su b/prod/hysh/bin/su deleted file mode 100644 index 3f4e394..0000000 --- a/prod/hysh/bin/su +++ /dev/null @@ -1 +0,0 @@ -local a=({...})[1]local b=syscall.getuid()if syscall.geteuid()~=0 then syscall.exec("/bin/su",{...})end;local c;if a then c=syscall.getuidbyname(a)else c=0 end;if not c then print("su: user '"..a.."' does not exist")syscall.exit(1)return end;if b~=0 then printInline("Password: ")local d=""while true do local e=syscall.read(0)if not e or e==""then elseif e=="\n"then syscall.write(1,"\n")break elseif e=="\b"then if#d>0 then d=d:sub(1,-2)syscall.write(1,"\b \b")end else d=d..e;syscall.write(1,"*")end end;local f,g=syscall.login(c,d)if not f then sleep(1)print("su: Authentication failure")syscall.exit(1)return end else syscall.setuid(c)end;local h=syscall.getpasswd(c)local i=h and h.shell or"/bin/hysh"local j=h and h.homedir or"/"local k=h and h.username or"Unknown"local l,m=pcall(syscall.chdir,j)if not l then j="/"syscall.chdir(j)end;syscall.setEnviron("HOME",j)syscall.setEnviron("USER",k)syscall.setEnviron("SHELL",i)local f,g=pcall(syscall.exec,i)if not f then print("su: cannot exec shell '"..i.."': "..tostring(g))syscall.exit(1)end diff --git a/prod/hysh/bin/sudo b/prod/hysh/bin/sudo deleted file mode 100644 index e2f59d0..0000000 --- a/prod/hysh/bin/sudo +++ /dev/null @@ -1 +0,0 @@ -local a=require("fs")local b={...}local c="root"local d=1;if b[d]=="-u"then d=d+1;local e=b[d]or"root"local f=tonumber(e)if f then local g=syscall.getpasswd(f)c=g and g.username or e else c=e end;d=d+1 end;local h=b[d]if not h or h==""then print("usage: sudo [-u user] [args...]")syscall.exit(1)return end;local i={}for j=d+1,#b do i[#i+1]=b[j]end;local k=syscall.getuid()local l=syscall.getUsername(k)or tostring(k)local m=syscall.getuidbyname(c)if not m then print("sudo: user '"..c.."' does not exist")syscall.exit(1)return end;if k~=0 then printInline("[sudo] password for root: ")local n=""while true do local o=syscall.read(0)if not o or o==""then elseif o=="\n"then syscall.write(1,"\n")break elseif o=="\b"then if#n>0 then n=n:sub(1,-2)syscall.write(1,"\b \b")end else n=n..o;syscall.write(1,"*")end end;local p,q=syscall.login(0,n)if not p then sleep(1)print("sudo: Authentication failure")syscall.exit(1)return end;if m~=k then syscall.setuid(m)end else if m~=k then syscall.setuid(m)end end;local r=""if h:find("/")then if a.exists(h)then r=h end else local s=string.split(syscall.getEnviron("PATH")or"/bin/",":")for t,u in ipairs(s)do local v=u..h;if a.exists(v)then r=v;break end end end;if r==""then print("sudo: command not found: "..h)syscall.exit(1)return end;local w=a.readAllText(r)local x,y=load(w,"@"..r)if not x then print("sudo: cannot load "..h..": "..tostring(y))syscall.exit(1)return end;local g=syscall.getpasswd(m)if g and g.homedir then syscall.setEnviron("HOME",g.homedir)end;syscall.setEnviron("USER",c)local p,q=xpcall(x,debug.traceback,table.unpack(i))if not p then print("sudo: "..h..": "..tostring(q))syscall.exit(1)end diff --git a/prod/hysh/bin/sysdump b/prod/hysh/bin/sysdump deleted file mode 100644 index 0c87cb2..0000000 --- a/prod/hysh/bin/sysdump +++ /dev/null @@ -1 +0,0 @@ -local a=...a=a or"/dev/tty/1"local b=syscall.sysdump()local c=syscall.open(a,"w")for d=1,#b do syscall.write(c,b[d].."\n")end;syscall.write(c,"Total # of syscalls: "..tostring(#b))syscall.close(c) diff --git a/prod/hysh/bin/umount b/prod/hysh/bin/umount deleted file mode 100644 index a0f9c15..0000000 --- a/prod/hysh/bin/umount +++ /dev/null @@ -1 +0,0 @@ -local a=syscall.getTask(syscall.getpid()).name;local b,c={},{l=false,["no-detach"]=false,help=false}for d,e in ipairs({...})do if e:sub(1,2)=="--"then local f=e:sub(3)if c[f]~=nil then c[f]=true else print(a..": unrecognised option '"..e.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end elseif e:sub(1,1)=="-"then for g=2,#e do local h=e:sub(g,g)if c[h]~=nil then c[h]=true else print(a..": invalid option '-"..h.."'")print("try '"..a.." --help' for more information.")syscall.exit(1)return end end else table.insert(b,e)end end;if c.help then print("Usage: "..a.." ")print(" "..a.." --no-detach ")print(" "..a.." -l ")print("")print("Unmount a filesystem mounted at .")print("")print(" unmount and auto-detach any loop device")print(" --no-detach unmount but keep the loop device attached")print(" -l forcibly detach a loop device (no unmount)")print("")print("Requires root.")return end;if c.l then if#b<1 then print(a..": -l requires a loop device id")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;local i=b[1]local j,k=pcall(syscall.lodetach,i)if not j then local l=tostring(k)if l:find("EPERM")then l="Permission denied"elseif l:find("ENXIO")then l="no such loop device '"..i.."'"elseif l:find("EBUSY")then l="'"..i.."' is still mounted - unmount first or omit -l"end;print(a..": "..l)syscall.exit(1)return end;syscall.devctl(1,"sfgc",0x00FFFF)print(a..": detached "..i)syscall.devctl(1,"sfgc",0xFFFFFF)return end;if#b<1 then print(a..": missing mount point operand")print("try '"..a.." --help' for more information.")syscall.exit(1)return end;local m=b[1]if m:sub(1,1)~="/"then m=syscall.getcwd().."/"..m end;local n=nil;if not c["no-detach"]then local o,p=pcall(syscall.lolist)if o then n={}for i in pairs(p)do n[#n+1]=i end end end;local j,k=pcall(syscall.umount,m)if not j then local l=tostring(k)if l:find("EPERM")then l="Permission denied"elseif l:find("EINVAL")then l="'"..b[1].."' is not a mount point"elseif l:find("EBUSY")then l="'"..b[1].."' is busy - close open files first"end;print(a..": "..l)syscall.exit(1)return end;syscall.devctl(1,"sfgc",0x00FFFF)print(a..": unmounted "..m)syscall.devctl(1,"sfgc",0xFFFFFF)if n then for d,i in ipairs(n)do local q=pcall(syscall.lodetach,i)if q then syscall.devctl(1,"sfgc",0xFF00FF)print(a..": auto-detached "..i)syscall.devctl(1,"sfgc",0xFFFFFF)end end end diff --git a/prod/hysh/bin/useradd b/prod/hysh/bin/useradd deleted file mode 100644 index e08f46d..0000000 --- a/prod/hysh/bin/useradd +++ /dev/null @@ -1 +0,0 @@ -local a={...}local b=1;local c={createHome=true}while b<=#a do local d=a[b]if d=="-p"then b=b+1;c.password=a[b]elseif d=="-g"then b=b+1;c.gid=tonumber(a[b])elseif d=="-d"then b=b+1;c.homedir=a[b]elseif d=="-s"then b=b+1;c.shell=a[b]elseif d=="-M"then c.createHome=false elseif d:sub(1,1)~="-"then c.username=d else print("useradd: unknown option: "..d)return end;b=b+1 end;if not c.username then print("Usage: useradd [-p password] [-g gid] [-d homedir] [-s shell] [-M] ")syscall.exit(1)return end;local e=c.password;if not e then printInline("New password: ")e=""while true do local f=syscall.read(0)if not f or f==""then elseif f=="\n"then syscall.write(1,"\n")break elseif f=="\b"then if#e>0 then e=e:sub(1,-2)syscall.write(1,"\b \b")end else e=e..f;syscall.write(1,"*")end end;printInline("Confirm password: ")local g=""while true do local f=syscall.read(0)if not f or f==""then elseif f=="\n"then syscall.write(1,"\n")break elseif f=="\b"then if#g>0 then g=g:sub(1,-2)syscall.write(1,"\b \b")end else g=g..f;syscall.write(1,"*")end end;if e~=g then print("useradd: passwords do not match")syscall.exit(1)return end end;local h,i=syscall.newuser(c.username,e,c.gid,c.homedir,c.shell or"/bin/hysh")if not h then print("useradd: "..tostring(i))syscall.exit(1)return end;if c.createHome then local j=c.homedir or"/home/"..c.username;local k,l=pcall(syscall.mkdir,j)if not k then print("useradd: warning: could not create home "..j..": "..tostring(l))end end;print("useradd: created user '"..c.username.."' with uid="..tostring(h)) diff --git a/prod/hysh/bin/userdel b/prod/hysh/bin/userdel deleted file mode 100644 index 9c6c9e1..0000000 --- a/prod/hysh/bin/userdel +++ /dev/null @@ -1 +0,0 @@ -local a={...}local b=false;local c=nil;for d,e in ipairs(a)do if e=="-r"then b=true elseif e:sub(1,1)~="-"then c=e else print("userdel: unknown option: "..e)syscall.exit(1)return end end;if not c then print("Usage: userdel [-r] ")syscall.exit(1)return end;local f=syscall.getuid(c)if not f then print("userdel: user '"..c.."' does not exist")syscall.exit(1)return end;local g=syscall.getpasswd(f)local h,i=syscall.deleteuser(f)if not h then print("userdel: "..tostring(i))syscall.exit(1)return end;if b and g and g.homedir then local j=require("fs")local k,l=pcall(function()local function m(n)for d,o in ipairs(j.list(n)or{})do local p=n.."/"..o;if j.isDir(p)then m(p)else syscall.remove(p)end end;syscall.remove(n)end;if j.exists(g.homedir)then m(g.homedir)end end)if not k then print("userdel: warning: could not remove home: "..tostring(l))end end;print("userdel: deleted user '"..c.."'") diff --git a/prod/hysh/bin/usermod b/prod/hysh/bin/usermod deleted file mode 100644 index 294e83a..0000000 --- a/prod/hysh/bin/usermod +++ /dev/null @@ -1 +0,0 @@ -local a={...}local b=1;local c={}while b<=#a do local d=a[b]if d=="-l"then b=b+1;c.newname=a[b]elseif d=="-p"then b=b+1;c.password=a[b]elseif d=="-g"then b=b+1;c.gid=tonumber(a[b])elseif d=="-d"then b=b+1;c.homedir=a[b]elseif d=="-s"then b=b+1;c.shell=a[b]elseif d=="-L"then c.lock=true elseif d=="-U"then c.unlock=true elseif d:sub(1,1)~="-"then c.username=d else print("usermod: unknown option: "..d)syscall.exit(1)return end;b=b+1 end;if not c.username then print("Usage: usermod [-l newname] [-p password] [-g gid] [-d homedir] [-s shell] [-L] [-U] ")syscall.exit(1)return end;if c.lock and c.unlock then print("usermod: -L and -U are mutually exclusive")syscall.exit(1)return end;local e=syscall.getuid(c.username)if not e then print("usermod: user '"..c.username.."' does not exist")syscall.exit(1)return end;local function f(g,...)local h,i=g(...)if not h then print("usermod: "..tostring(i))syscall.exit(1)end end;if c.newname then f(syscall.setusername,e,c.newname)end;if c.password then f(syscall.setpassword,e,c.password)end;if c.gid then f(syscall.setgid,e,c.gid)end;if c.homedir then f(syscall.sethomedir,e,c.homedir)end;if c.shell then f(syscall.setshell,e,c.shell)end;if c.lock then f(syscall.lockuser,e)end;if c.unlock then f(syscall.unlockuser,e)end;print("usermod: updated user '"..c.username.."'") diff --git a/prod/hysh/bin/yes b/prod/hysh/bin/yes deleted file mode 100644 index f9b868d..0000000 --- a/prod/hysh/bin/yes +++ /dev/null @@ -1 +0,0 @@ -local a={...}while true do if#a==0 then print("y")else print(table.concat(a," "))end end diff --git a/prod/iniparse/lib/iniparse b/prod/iniparse/lib/iniparse deleted file mode 100644 index 3578307..0000000 --- a/prod/iniparse/lib/iniparse +++ /dev/null @@ -1 +0,0 @@ -local a={}function a.parse(b)local c={}local d=nil;for e in b:gmatch("[^\r\n]+")do e=e:match("^%s*(.-)%s*$")if e~=""and not e:match("^[;#]")then local f=e:match("^%[(.-)%]$")if f then d=f;c[d]=c[d]or{}else local g,h=e:match("^(.-)=(.*)$")if g then g=g:match("^%s*(.-)%s*$")h=h:match("^%s*(.-)%s*$")if d then c[d][g]=h else c[g]=h end end end end end;return c end;return a diff --git a/prod/json/lib/json b/prod/json/lib/json deleted file mode 100644 index f3e5b56..0000000 --- a/prod/json/lib/json +++ /dev/null @@ -1 +0,0 @@ -local a={_version="0.1.2"}local b;local c={["\\"]="\\",["\""]="\"",["\b"]="b",["\f"]="f",["\n"]="n",["\r"]="r",["\t"]="t"}local d={["/"]="/"}for e,f in pairs(c)do d[f]=e end;local function g(h)return"\\"..(c[h]or string.format("u%04x",h:byte()))end;local function i(j)return"null"end;local function k(j,l)local m={}l=l or{}if l[j]then error("circular reference")end;l[j]=true;if rawget(j,1)~=nil or next(j)==nil then local n=0;for e in pairs(j)do if type(e)~="number"then error("invalid table: mixed or invalid key types")end;n=n+1 end;if n~=#j then error("invalid table: sparse array")end;for o,f in ipairs(j)do table.insert(m,b(f,l))end;l[j]=nil;return"["..table.concat(m,",").."]"else for e,f in pairs(j)do if type(e)~="string"then error("invalid table: mixed or invalid key types")end;table.insert(m,b(e,l)..":"..b(f,l))end;l[j]=nil;return"{"..table.concat(m,",").."}"end end;local function p(j)return'"'..j:gsub('[%z\1-\31\\"]',g)..'"'end;local function q(j)if j~=j or j<=-math.huge or j>=math.huge then error("unexpected number value '"..tostring(j).."'")end;return string.format("%.14g",j)end;local r={["nil"]=i,["table"]=k,["string"]=p,["number"]=q,["boolean"]=tostring}b=function(j,l)local s=type(j)local t=r[s]if t then return t(j,l)end;error("unexpected type '"..s.."'")end;function a.encode(j)return b(j)end;local u;local function v(...)local m={}for o=1,select("#",...)do m[select(o,...)]=true end;return m end;local w=v(" ","\t","\r","\n")local x=v(" ","\t","\r","\n","]","}",",")local y=v("\\","/",'"',"b","f","n","r","t","u")local z=v("true","false","null")local A={["true"]=true,["false"]=false,["null"]=nil}local function B(C,D,E,F)for o=D,#C do if E[C:sub(o,o)]~=F then return o end end;return#C+1 end;local function G(C,D,H)local I=1;local J=1;for o=1,D-1 do J=J+1;if C:sub(o,o)=="\n"then I=I+1;J=1 end end;error(string.format("%s at line %d col %d",H,I,J))end;local function K(n)local t=math.floor;if n<=0x7f then return string.char(n)elseif n<=0x7ff then return string.char(t(n/64)+192,n%64+128)elseif n<=0xffff then return string.char(t(n/4096)+224,t(n%4096/64)+128,n%64+128)elseif n<=0x10ffff then return string.char(t(n/262144)+240,t(n%262144/4096)+128,t(n%4096/64)+128,n%64+128)end;error(string.format("invalid unicode codepoint '%x'",n))end;local function L(M)local N=tonumber(M:sub(1,4),16)local O=tonumber(M:sub(7,10),16)if O then return K((N-0xd800)*0x400+O-0xdc00+0x10000)else return K(N)end end;local function P(C,o)local m=""local Q=o+1;local e=Q;while Q<=#C do local R=C:byte(Q)if R<32 then G(C,Q,"control character in string")elseif R==92 then m=m..C:sub(e,Q-1)Q=Q+1;local h=C:sub(Q,Q)if h=="u"then local S=C:match("^[dD][89aAbB]%x%x\\u%x%x%x%x",Q+1)or C:match("^%x%x%x%x",Q+1)or G(C,Q-1,"invalid unicode escape in string")m=m..L(S)Q=Q+#S else if not y[h]then G(C,Q-1,"invalid escape char '"..h.."' in string")end;m=m..d[h]end;e=Q+1 elseif R==34 then m=m..C:sub(e,Q-1)return m,Q+1 end;Q=Q+1 end;G(C,o,"expected closing quote for string")end;local function T(C,o)local R=B(C,o,x)local M=C:sub(o,R-1)local n=tonumber(M)if not n then G(C,o,"invalid number '"..M.."'")end;return n,R end;local function U(C,o)local R=B(C,o,x)local V=C:sub(o,R-1)if not z[V]then G(C,o,"invalid literal '"..V.."'")end;return A[V],R end;local function W(C,o)local m={}local n=1;o=o+1;while 1 do local R;o=B(C,o,w,true)if C:sub(o,o)=="]"then o=o+1;break end;R,o=u(C,o)m[n]=R;n=n+1;o=B(C,o,w,true)local X=C:sub(o,o)o=o+1;if X=="]"then break end;if X~=","then G(C,o,"expected ']' or ','")end end;return m,o end;local function Y(C,o)local m={}o=o+1;while 1 do local Z,j;o=B(C,o,w,true)if C:sub(o,o)=="}"then o=o+1;break end;if C:sub(o,o)~='"'then G(C,o,"expected string for key")end;Z,o=u(C,o)o=B(C,o,w,true)if C:sub(o,o)~=":"then G(C,o,"expected ':' after key")end;o=B(C,o+1,w,true)j,o=u(C,o)m[Z]=j;o=B(C,o,w,true)local X=C:sub(o,o)o=o+1;if X=="}"then break end;if X~=","then G(C,o,"expected '}' or ','")end end;return m,o end;local _={['"']=P,["0"]=T,["1"]=T,["2"]=T,["3"]=T,["4"]=T,["5"]=T,["6"]=T,["7"]=T,["8"]=T,["9"]=T,["-"]=T,["t"]=U,["f"]=U,["n"]=U,["["]=W,["{"]=Y}u=function(C,D)local X=C:sub(D,D)local t=_[X]if t then return t(C,D)end;G(C,D,"unexpected character '"..X.."'")end;function a.decode(C)if type(C)~="string"then error("expected argument of type string, got "..type(C))end;local m,D=u(C,B(C,1,w,true))D=B(C,D,w,true)if D<=#C then G(C,D,"trailing garbage")end;return m end;return a diff --git a/prod/lua/bin/lua b/prod/lua/bin/lua deleted file mode 100644 index fcfe302..0000000 --- a/prod/lua/bin/lua +++ /dev/null @@ -1 +0,0 @@ -local a=0xFFFF00;local b=0xDBDBDB;local c=0x00FFFF;local d=0xFF0000;local e=0x00FF00;local f=0x00FF88;local g=0x24FFFF;local h=0xFF6D00;local i=0x6D6D6D;local j=0xDBDBDB;local function k(l)syscall.devctl(1,"sfgc",l)end;local function m(n)syscall.write(1,tostring(n))end;local o=6;local p=64;local function q(r,s,t)s=s or 0;t=t or{}local u=type(r)if u=="nil"then k(i)m("nil")elseif u=="boolean"then k(h)m(tostring(r))elseif u=="number"then k(g)if r~=r then m("nan")elseif r==math.huge then m("inf")elseif r==-math.huge then m("-inf")elseif r==math.floor(r)and math.abs(r)<1e15 then m(tostring(math.floor(r)))else m(tostring(r))end elseif u=="string"then k(f)local n=string.format("%q",r)m(n)elseif u=="function"then k(j)m(tostring(r))elseif u=="table"then if t[r]then k(j)m("")return end;if s>=o then k(j)m("")return end;t[r]=true;local v=string.rep(" ",s)local w=string.rep(" ",s+1)local x={}local y={}local z=#r;for A in pairs(r)do if type(A)=="number"and A>=1 and A<=z and A==math.floor(A)then x[#x+1]=A else y[#y+1]=A end end;table.sort(x)table.sort(y,function(B,C)local D,E=type(B),type(C)if D==E then if D=="string"then return Bp then return true end;m(w)if type(A)=="number"and x[A]then else if type(A)=="string"and A:match("^[a-zA-Z_][a-zA-Z0-9_]*$")then k(e)m(A)else k(j)m("[")q(A,s+1,t)k(j)m("]")end;k(j)m(" = ")end;q(I,s+1,t)k(j)if not J then m(",")end;m("\n")end;for K,A in ipairs(x)do m(w)q(r[A],s+1,t)k(j)if K=p then k(i)m(w.."-- ..."..F-G.." more entries\n")break end end;if G

=F;m(w)if type(A)=="string"and A:match("^[a-zA-Z_][a-zA-Z0-9_]*$")then k(e)m(A)else k(j)m("[")q(A,s+1,t)k(j)m("]")end;k(j)m(" = ")q(r[A],s+1,t)k(j)G=G+1;if G=p then local L=F-G;if L>0 then k(i)m(w.."-- ..."..L.." more entries\n")end;break end end end;k(j)m(v.."}")t[r]=nil else k(j)m(tostring(r))end;k(1)end;local function M(...)local N=select("#",...)if N==0 then return end;for K=1,N do if K>1 then k(j)m("\t")end;q(select(K,...),0,{})end;m("\n")k(1)end;local O=setmetatable({},{__index=_ENV})O._G=O;O.print=function(...)local N=select("#",...)for K=1,N do if K>1 then m("\t")end;q(select(K,...),0,{})end;m("\n")k(1)end;O.pp=function(r)q(r,0,{})m("\n")k(1)end;O.exit=setmetatable({},{__tostring=function()return"function: exit()"end,__call=function()syscall.exit()end})local function P(Q)local R=load("return "..Q,"@lua","t",O)if R then return R,true end;local S,T=load(Q,"@lua","t",O)return S,false,T end;local function U(Q)local V,T=load(Q,"@lua","t",O)return T and(T:find("")~=nil or T:find("'end'")~=nil or T:find("'then'")~=nil or T:find("'until'")~=nil)end;local function W(X)return tostring(X):gsub("^%[string .-%]:",""):gsub("^@lua:",""):gsub("stack traceback:.*",""):match("^%s*(.-)%s*$")end;local function Y(Q)local Z,_,T=P(Q)if not Z then k(d)m("[error] ")k(1)m(W(T).."\n")return end;local a0=table.pack(xpcall(Z,debug.traceback))local a1=table.remove(a0,1)a0.n=a0.n-1;if not a1 then k(d)m("[error] ")k(1)m(W(a0[1]).."\n")elseif _ and a0.n>0 then k(c)m("= ")M(table.unpack(a0,1,a0.n))end end;local function a2(a3,a4)k(a)m(a3)k(1)local a5=syscall.devctl(1,"gpos")local a6=tonumber(a5:sub(1,a5:find(";")-1))local a7=tonumber(a5:sub(a5:find(";")+1))local a8=""local a9=1;local aa=0;local ab=false;local ac=true;local function ad()syscall.devctl(1,"spos",a6,a7)m(a8:sub(1,a9-1))if ab then syscall.devctl(1,"sfgc",0x000000)syscall.devctl(1,"sbgc",1)end;m(a9>#a8 and" "or a8:sub(a9,a9))syscall.devctl(1,"sfgc",0xFFFFFF)syscall.devctl(1,"sbgc",16)m(a8:sub(a9+1).." ")ac=false end;while true do local ae=syscall.read(0)if ae and ae~=""then if ae==""then if a9>1 then a9=a9-1;ac=true end elseif ae==""then if a9<=#a8 then a9=a9+1;ac=true end elseif ae==""then if a4 and aa<#a4 then aa=aa+1;a8=a4[#a4-aa+1]a9=#a8+1;ac=true end elseif ae==""then if aa>1 then aa=aa-1;a8=a4[#a4-aa+1]a9=#a8+1;ac=true elseif aa==1 then aa=0;a8=""a9=1;ac=true end elseif ae=="\b"then if a9>1 then a8=a8:sub(1,a9-2)..a8:sub(a9)a9=a9-1;ac=true end elseif ae=="\n"then syscall.devctl(1,"sfgc",0xFFFFFF)syscall.devctl(1,"sbgc",16)syscall.devctl(1,"spos",a6,a7)m(a8 .." \n")return a8 elseif#ae==1 and ae:byte(1)>=32 and ae:byte(1)<127 then a8=string.sub(a8,1,a9-1)..ae..string.sub(a8,a9)a9=a9+1;ac=true end end;local af=math.floor(syscall.getUptime()/500)%2==0;if af~=ab then ab=af;ac=true end;if ac then ad()end end end;k(a)m("HyperionOS ".._VERSION.."\n")k(i)m("Interactive Lua REPL. exit() to quit.\n\n")k(1)local a4={}while true do local Q=a2("lua> ",a4)if Q~=""then while U(Q)do Q=Q.."\n"..a2("... ",nil)end;if Q~=a4[#a4]then a4[#a4+1]=Q end;Y(Q)end end diff --git a/prod/micro/bin/micro b/prod/micro/bin/micro deleted file mode 100644 index 1bae4dc..0000000 --- a/prod/micro/bin/micro +++ /dev/null @@ -1 +0,0 @@ -local a={...}local function b()local c=syscall.devctl(1,"size")return tonumber(c:match("^(%d+)"))or 80,tonumber(c:match(";(%d+)$"))or 24 end;local function d(e,f)syscall.devctl(1,"spos",e,f)end;local function g(h)syscall.devctl(1,"sfgc",h)end;local function i(h)syscall.devctl(1,"sbgc",h)end;local function j(c)if c and c~=""then syscall.write(1,c)end end;local function k()syscall.devctl(1,"clear")end;local l,m=b()local n=m-2;local o={""}local p=1;local q=1;local r=0;local s=true;local t=nil;local u=""local v=false;local w=nil;local x=""local y=0;local z=false;local function A(B)if B:sub(1,1)=="/"then return B end;local C=syscall.getcwd()C=C:gsub("/+$","")return C.."/"..B end;local function D(E)if not syscall.exists(E)then o={""}u="[new file]"return end;local F=syscall.open(E,"r")local G=""while true do local h=syscall.read(F,4096)if not h or h==""then break end;G=G..h end;syscall.close(F)o={}for H in(G.."\n"):gmatch("([^\n]*)\n")do table.insert(o,H)end;if#o>1 and o[#o]==""and G:sub(-1)=="\n"then table.remove(o)end;if#o==0 then o={""}end end;local function I(E)local J,K=pcall(function()local F=syscall.open(E,"w")for L,H in ipairs(o)do syscall.write(F,H)if L<#o then syscall.write(F,"\n")end end;syscall.write(F,"\n")syscall.close(F)end)if J then u="Saved: "..E;v=false else u="Save failed: "..tostring(K)v=true end end;local function M(N)return math.max(1,math.ceil(#N/l))end;local function O(P,Q)return math.floor((Q-1)/l)end;local function R()local S={}local T=0;for P=1,#o do local U=#o[P]local V=M(o[P])for W=0,V-1 do T=T+1;S[T]={P,W*l+1}end end;return S,T end;local function X(S)local Y=O(q,p)for T,Z in ipairs(S)do if Z[1]==q and math.floor((Z[2]-1)/l)==Y then return T end end;return 1 end;local function _()local a0=#o[q]+1;if p>a0 then p=a0 end;if p<1 then p=1 end end;local function a1(S)local a2=X(S)if a2-1=r+n then r=a2-n end;if r<0 then r=0 end end;local function a3(c,a4)if#c>=a4 then return c:sub(1,a4)end;return c..string.rep(" ",a4-#c)end;local function a5()d(1,1)i(0x0000FF)g(0x000000)local a6=" edit"..(t and" - "..t or"")if s then a6=a6 .." [+]"end;local a7=tostring(q)..","..tostring(p).." "j(a3(a6 ..string.rep(" ",math.max(1,l-#a6-#a7))..a7,l))i(0x000000)g(0xFFFFFF)end;local function a8()d(1,m)i(0x0000FF)g(0x000000)if u~=""then if v then i(2)end;j(a3(" "..u,l))u=""v=false else j(a3(" ^W Save ^X Quit+Save ^P Quit ^K Cut ^U Paste ^F Find ^G Go",l))end;i(0x000000)g(0xFFFFFF)end;local function a9(S)local aa=X(S)local ab=O(q,p)local ac=p-ab*l;for ad=1,n do local T=r+ad;d(1,ad+1)local Z=S[T]if Z then local P=Z[1]local ae=Z[2]local af=o[P]:sub(ae,ae+l-1)local ag=T==aa;if ag then local ah=ac;ah=math.min(ah,#af+1)local ai=af:sub(1,ah-1)local aj=ah>#af and" "or af:sub(ah,ah)local ak=af:sub(ah+1)g(0xFFFFFF)i(0x000000)j(ai)if z then g(0x000000)i(0xFFFFFF)else g(0xFFFFFF)i(0x000000)end;j(aj)g(0xFFFFFF)i(0x000000)j(ak)local al=#ai+1+#ak;if al0 then ar=ar:sub(1,-2)end else local at=as:byte(1)if at>=32 and at<127 then ar=ar..as:sub(1,1)end end end end;local function au(h)local H=o[q]o[q]=H:sub(1,p-1)..h..H:sub(p)p=p+1;s=true end;local function av()if p>1 then local H=o[q]o[q]=H:sub(1,p-2)..H:sub(p)p=p-1;s=true elseif q>1 then local aw=o[q-1]p=#aw+1;o[q-1]=aw..o[q]table.remove(o,q)q=q-1;s=true end end;local function ax()local H=o[q]if p<=#H then o[q]=H:sub(1,p-1)..H:sub(p+1)s=true elseif q<#o then o[q]=H..o[q+1]table.remove(o,q+1)s=true end end;local function ay()local H=o[q]local az=H:sub(1,p-1)local aA=H:sub(p)local aB=az:match("^(%s*)")or""o[q]=az;table.insert(o,q+1,aB..aA)q=q+1;p=#aB+1;s=true end;local function aC()w=o[q]table.remove(o,q)if#o==0 then o={""}end;if q>#o then q=#o end;p=1;s=true;u="Cut"end;local function aD()if not w then u="Nothing to paste"return end;table.insert(o,q,w)q=q+1;p=1;s=true;u="Pasted"end;local function aE()if x==""then local B=ao("Find: ","")if not B or B==""then s=true;return end;x=B;y=0 end;local aF=y>0 and y or q;for L=1,#o do local aG=(aF-1+L)%#o+1;if o[aG]:find(x)then q=aG;y=aG;p=o[aG]:find(x)or 1;u="Found: line "..aG;s=true;return end end;u="Not found: "..x;v=true;s=true end;local function aH()local B=ao("Go to line: ","")if not B then s=true;return end;local aI=tonumber(B)if not aI then u="Not a number"v=true;s=true;return end;q=math.max(1,math.min(#o,math.floor(aI)))p=1;u="Line "..q;s=true end;local function aJ()if not t then local B=ao("Save as: ","")s=true;if not B or B==""then return false end;t=A(B)end;I(t)s=true;return not v end;local function aK(S)local a2=X(S)if a2<=1 then return end;local aL=S[a2-1]if not aL then return end;local aM=aL[1]local aN=aL[2]+(p-1)%l;p=math.min(aN,#o[aM]+1)q=aM end;local function aO(S)local a2=X(S)local aP=S[a2+1]if not aP then return end;local aM=aP[1]local aN=aP[2]+(p-1)%l;p=math.min(aN,#o[aM]+1)q=aM end;if a[1]then t=A(a[1])D(t)end;k()local aQ=true;while aQ do local S=R()local as=syscall.read(0)if as and as~=""then local at=as:byte(1)if as==""then aK(S)s=true elseif as==""then aO(S)s=true elseif as==""then if p<=#o[q]then p=p+1 elseif q<#o then q=q+1;p=1 end;s=true elseif as==""then if p>1 then p=p-1 elseif q>1 then q=q-1;p=#o[q]+1 end;s=true elseif as==""then p=1;s=true elseif as==""then p=#o[q]+1;s=true elseif as=="[5~"then for aR=1,n do aK(S)end;s=true elseif as=="[6~"then for aR=1,n do aO(S)end;s=true elseif as=="[3~"then ax()elseif as=="\n"then ay()elseif as=="\b"then av()elseif as=="\t"then for aR=1,4 do au(" ")end elseif at==6 then local B=ao("Find: ",x)s=true;if B then x=B;y=0;aE()end elseif at==7 then aH()elseif at==11 then aC()elseif at==14 then if x==""then local B=ao("Find: ","")s=true;if B then x=B;y=0 end end;aE()elseif at==16 then if s then local B=ao("Unsaved changes. Quit? [y/N] ","")s=true;if B and B:lower()=="y"then aQ=false end else aQ=false end elseif at==21 then aD()elseif at==23 then aJ()elseif at==24 then aJ()aQ=false else if at>=32 and at<127 then au(as:sub(1,1))end end end;local aS=math.floor(syscall.getUptime()/500)%2==0;if aS~=z then z=aS;s=true end;if s then _()an()s=false end end;k()g(0xFFFFFF)i(0x000000)d(1,1)print("edit: exited"..(t and" - "..t or"")) diff --git a/prod/sed/bin/sed b/prod/sed/bin/sed deleted file mode 100644 index 9362053..0000000 --- a/prod/sed/bin/sed +++ /dev/null @@ -1 +0,0 @@ -local a=syscall.getTask(syscall.getpid()).name;local b={}local c={}local d=false;local e=false;local f={...}local g=1;while g<=#f do local h=f[g]if h=="-n"then d=true elseif h=="-i"then e=true elseif h=="-e"then g=g+1;if not f[g]then print(a..": option -e requires an argument")syscall.exit(1)return end;table.insert(b,f[g])elseif h:sub(1,2)=="-e"then table.insert(b,h:sub(3))elseif h=="--help"then print("Usage: "..a.." [OPTION]... SCRIPT [FILE...]")print(" "..a.." [OPTION]... -e SCRIPT... [FILE...]")print("Stream editor. Reads FILE(s) (or stdin) line by line,")print("applies SCRIPT, and writes results to stdout.")print("")print("Commands:")print(" s/REGEX/REPL/[flags] substitute (flags: g global, i ignore-case, p print)")print(" d delete line (skip to next)")print(" p print current line")print(" q quit")print(" = print current line number")print(" y/src/dst/ transliterate characters")print("")print("Addressing (prefix any command):")print(" N line number N")print(" $ last line")print(" /REGEX/ lines matching regex")print(" N,M line range")print(" N,/REGEX/ from line N until regex match")print("")print("Options:")print(" -n suppress default output")print(" -e SCRIPT add script expression")print(" -i edit file in-place")print(" --help display this help and exit")return elseif h:sub(1,1)=="-"then print(a..": unknown option: "..h)syscall.exit(1)return else if#b==0 then table.insert(b,h)else table.insert(c,h)end end;g=g+1 end;if#b==0 then print(a..": no script specified")syscall.exit(1)return end;local i=table.concat(b,"\n")local function j(k)return k:gsub("([%(%)%.%%%+%-%*%?%[%^%$])","%%%1")end;local function l(m,n)m=m:gsub("\\%(","("):gsub("\\%)",")")m=m:gsub("\\1","%%1"):gsub("\\2","%%2")return m end;local function o(k,p,q)local r={}while p<=#k do local s=k:sub(p,p)if s=="\\"and p<#k then p=p+1;local t=k:sub(p,p)if t==q then table.insert(r,q)elseif t=="n"then table.insert(r,"\n")else table.insert(r,"\\"..t)end elseif s==q then return table.concat(r),p+1 else table.insert(r,s)end;p=p+1 end;return table.concat(r),p end;local function u(k,p)local s=k:sub(p,p)if s==""then return nil,p end;if s:match("%d")then local v=k:match("^(%d+)",p)return{type="line",n=tonumber(v)},p+#v elseif s=="$"then return{type="last"},p+1 elseif s=="/"then local m,w=o(k,p+1,"/")return{type="regex",pat=m},w end;return nil,p end;local function x(y)local z={}local p=1;local A=#y;local function B()while p<=A and(y:sub(p,p)==" "or y:sub(p,p)=="\t")do p=p+1 end end;while p<=A do B()if p>A then break end;local s=y:sub(p,p)if s=="\n"or s==";"then p=p+1 elseif s=="#"then while p<=A and y:sub(p,p)~="\n"do p=p+1 end else local C,D;C,p=u(y,p)B()if C and p<=A and y:sub(p,p)==","then p=p+1;B()D,p=u(y,p)end;B()if p>A then break end;local E=y:sub(p,p)p=p+1;if E=="s"then local q=y:sub(p,p)p=p+1;local m,F=o(y,p,q)p=F;local G,H=o(y,p,q)p=H;local I=""while p<=A and y:sub(p,p):match("[giIp]")do I=I..y:sub(p,p)p=p+1 end;table.insert(z,{addr1=C,addr2=D,cmd="s",pat=m,repl=G,flags=I})elseif E=="y"then local q=y:sub(p,p)p=p+1;local J,F=o(y,p,q)p=F;local K,H=o(y,p,q)p=H;table.insert(z,{addr1=C,addr2=D,cmd="y",src=J,dst=K})elseif E=="d"or E=="p"or E=="q"or E=="="then table.insert(z,{addr1=C,addr2=D,cmd=E})elseif E=="{"then local L=1;local M=p;while p<=A and L>0 do local N=y:sub(p,p)if N=="{"then L=L+1 elseif N=="}"then L=L-1 end;p=p+1 end;local O=y:sub(M,p-2)local P=x(O)for Q,R in ipairs(P)do R.addr1=R.addr1 or C;R.addr2=R.addr2 or D end;for Q,R in ipairs(P)do table.insert(z,R)end elseif E=="\n"or E==";"then else end end end;return z end;local z=x(i)local S={}local function T(E,U,V,W,X)local Y=E.addr1;local Z=E.addr2;if not Y then return true end;local function _(a0,a1,a2)if a0.type=="line"then return a1==a0.n elseif a0.type=="last"then return W elseif a0.type=="regex"then return a2:find(l(a0.pat))~=nil end;return false end;if not Z then return _(Y,U,V)end;if S[X]then local a3;if Z.type=="line"then a3=U>=Z.n elseif Z.type=="last"then a3=W elseif Z.type=="regex"then a3=V:find(l(Z.pat))~=nil end;if a3 then S[X]=false end;return true else if _(Y,U,V)then if Z.type=="line"and Z.n<=U then else S[X]=true end;return true end;return false end end;local function a4(V,m,G,I)local a5=I:find("g")~=nil;local n=I:find("[iI]")~=nil;local a6=l(m,n)local function a7(a8,...)local a9={...}local r={}local aa=G;local ab=1;while ab<=#aa do local ac=aa:sub(ab,ab)if ac=="&"then table.insert(r,a8)elseif ac=="\\"and ab<#aa then ab=ab+1;local t=aa:sub(ab,ab)if t:match("%d")then local ad=tonumber(t)table.insert(r,a9[ad]or"")elseif t=="n"then table.insert(r,"\n")else table.insert(r,t)end else table.insert(r,ac)end;ab=ab+1 end;return table.concat(r)end;local ae;local af=false;if a5 then ae=V:gsub(a6,a7)af=ae~=V else local k,ag,a8;local ah={V:find(a6)}if ah[1]then k=ah[1]ag=ah[2]local a9={}for X=3,#ah do a9[#a9+1]=ah[X]end;local ai=V:sub(k,ag)local aj=a7(ai,table.unpack(a9))ae=V:sub(1,k-1)..aj..V:sub(ag+1)af=true else ae=V end end;return ae,af end;local function ak(V,y,al)local r={}for X=1,#V do local s=V:sub(X,X)local ad=y:find(s,1,true)if ad and ad<=#al then table.insert(r,al:sub(ad,ad))else table.insert(r,s)end end;return table.concat(r)end;local function am(an,ao)local ap=#an;for U,V in ipairs(an)do local W=U==ap;local aq=false;local ar=false;local as=false;local at=V:gsub("\n$","")for X,E in ipairs(z)do if T(E,U,at,W,X)then if E.cmd=="d"then aq=true;break elseif E.cmd=="p"then table.insert(ao,at)elseif E.cmd=="="then table.insert(ao,tostring(U))elseif E.cmd=="q"then if not d then table.insert(ao,at)end;as=true;break elseif E.cmd=="s"then local au,af=a4(at,E.pat,E.repl,E.flags)at=au;if af and E.flags:find("p")then table.insert(ao,at)end elseif E.cmd=="y"then at=ak(at,E.src,E.dst)end end end;if as then break end;if not aq and not d then table.insert(ao,at)end end end;local function av(aw)local an={}local ax=""while true do local ay=syscall.read(aw,1024)if not ay or ay==""then break end;ax=ax..ay end;for V in(ax.."\n"):gmatch("([^\n]*)\n")do table.insert(an,V)end;if ax~=""and ax:sub(-1)~="\n"and an[#an]==""then table.remove(an)end;return an end;local function az(aA)local aw;if aA then local aB,aC=pcall(function()aw=syscall.open(aA,"r")end)if not aB then print(a..": "..aA..": "..tostring(aC))return false end else aw=0 end;local an=av(aw)if aA then syscall.close(aw)end;S={}local ao={}am(an,ao)if e and aA then local aD=syscall.open(aA,"w")for Q,aE in ipairs(ao)do syscall.write(aD,aE.."\n")end;syscall.close(aD)else for Q,aE in ipairs(ao)do print(aE)end end;return true end;if#c==0 then az(nil)else for Q,aF in ipairs(c)do local aG=aF;if aG:sub(1,1)~="/"then aG=syscall.getcwd().."/"..aF end;az(aG)end end diff --git a/prod/spm/bin/spm b/prod/spm/bin/spm deleted file mode 100644 index 9756ac9..0000000 --- a/prod/spm/bin/spm +++ /dev/null @@ -1,6 +0,0 @@ -local args={...} - -local json=require("json") -local http=require("http") -local rootRepo="https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm/spm.src" - diff --git a/prod/sysinit/sbin/init b/prod/sysinit/sbin/init deleted file mode 100644 index 5071168..0000000 --- a/prod/sysinit/sbin/init +++ /dev/null @@ -1,4 +0,0 @@ -local args={...} -syscall.remove("/sbin/init") -syscall.symlink("/usr/lib/sysinit/sysinit", "/sbin/init") -syscall.exec("/sbin/init", args) \ No newline at end of file diff --git a/prod/sysinit/usr/lib/sysinit/sysinit b/prod/sysinit/usr/lib/sysinit/sysinit deleted file mode 100644 index 0d16d30..0000000 --- a/prod/sysinit/usr/lib/sysinit/sysinit +++ /dev/null @@ -1 +0,0 @@ -local a=...local b=require("fs")a.log("Sysinit started...")for c,d in pairs(a.processes)do a.log("Spawning kernel task "..c)syscall.spawn(function()local e,f=pcall(d)if not e then a.log("Error executing kernel task '"..c.."': "..f,"ERROR",0xFF0000)else a.log("Successfully executed kernel task: "..c)end end,c)end;if not b.exists("/bin/startup")then b.mkdir("/bin/startup")end;local g=b.list("/bin/startup")if not g then error("Failed to list /bin/startup")end;for c,d in ipairs(g)do if d:sub(-4)==".lua"then local h="/bin/startup/"..d;a.log("Executing startup script: "..h)local i,f=load(b.readAllText(h),"@"..h)if not i then a.log("Error loading startup script '"..h.."': "..f,"ERROR",0xFF0000)else syscall.spawn(function()syscall.setuid(1)local e,f=pcall(i)if not e then a.log("Error executing startup script '"..h.."': "..f,"ERROR",0xFF0000)else a.log("Successfully executed startup script: "..h)end end,"startup:"..d)end end end;while true do sleep(5)a.saveLog()end diff --git a/spm.json b/spm.json new file mode 100644 index 0000000..495bdbb --- /dev/null +++ b/spm.json @@ -0,0 +1,28 @@ +{ + "packages":{ + "spm":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/spm.pkg", + "HyperionOS":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/HyperionOS.pkg", + "Hyperion-kernel":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-kernel.pkg", + "Hyperion-core":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-core.pkg", + "Hyperion-firmware-ac":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-firmware-ac.pkg", + "Hyperion-firmware-ccpc":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-firmware-ccpc.pkg", + "Hyperion-firmware-cct":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-firmware-cct.pkg", + "Hyperion-firmware-oc":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-firmware-oc.pkg", + "sysinit":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/sysinit.pkg", + "hysh":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/hysh.pkg", + "bit32":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/bit32.pkg", + "blake2s":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/blake2s.pkg", + "deflate":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/deflate.pkg", + "iniparse":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/iniparse.pkg", + "json":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/json.pkg", + "lua":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/lua.pkg", + "micro":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/micro.pkg", + "xz":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/xz.pkg" + }, + "refs":[ + "https://git.astronand.dev/Astronand/HyperionOS-packages/raw/branch/main/spm.json" + ], + "maintainers":[ + "Astronand" + ] +} \ No newline at end of file diff --git a/spm/pkg/HyperionOS-bash.pkg b/spm/pkg/HyperionOS-bash.pkg deleted file mode 100644 index 9789f3b..0000000 --- a/spm/pkg/HyperionOS-bash.pkg +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Name": "HyperionOS bash", - "Version": "1.0.0", - "Publishers": ["HyperionOS Dev Team"], - "Description": "Basic bash shell for HyperionOS", - "Dependencies": [ - "HyperionOS" - ], - "Tar": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm/tar/HyperionOS-kernel.tar.gz" -} \ No newline at end of file diff --git a/spm/pkg/HyperionOS-core.pkg b/spm/pkg/HyperionOS-core.pkg deleted file mode 100644 index 64c5b5b..0000000 --- a/spm/pkg/HyperionOS-core.pkg +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Name": "HyperionOS core", - "Version": "1.0.0", - "Publishers": ["HyperionOS Dev Team"], - "Description": "Core system files and librarys for HyperionOS", - "Dependencies": [ - "HyperionOS" - ], - "Tar": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm/tar/HyperionOS-core.tar.gz" -} \ No newline at end of file diff --git a/spm/pkg/HyperionOS-firmware-cct.pkg b/spm/pkg/HyperionOS-firmware-cct.pkg deleted file mode 100644 index be9ddb6..0000000 --- a/spm/pkg/HyperionOS-firmware-cct.pkg +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Name": "HyperionOS CCT Firmware", - "Version": "1.0.0", - "Publishers": ["HyperionOS Dev Team"], - "Description": "The ComputerCraftTweaked firmware package for HyperionOS.", - "Dependencies": [ - "HyperionOS-kernel" - ], - "Tar": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm/tar/HyperionOS-kernel.tar.gz" -} \ No newline at end of file diff --git a/spm/pkg/HyperionOS-firmware-oc.pkg b/spm/pkg/HyperionOS-firmware-oc.pkg deleted file mode 100644 index 9130f92..0000000 --- a/spm/pkg/HyperionOS-firmware-oc.pkg +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Name": "HyperionOS OC Firmware", - "Version": "1.0.0", - "Publishers": ["HyperionOS Dev Team"], - "Description": "The OpenComputers firmware package for HyperionOS.", - "Dependencies": [ - "HyperionOS-kernel" - ], - "Tar": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm/tar/HyperionOS-kernel.tar.gz" -} \ No newline at end of file diff --git a/spm/pkg/HyperionOS-kernel.pkg b/spm/pkg/HyperionOS-kernel.pkg deleted file mode 100644 index f88c6cb..0000000 --- a/spm/pkg/HyperionOS-kernel.pkg +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Name": "HyperionOS Kernel", - "Version": "1.0.0", - "Publishers": ["HyperionOS Dev Team"], - "Description": "The kernel package for HyperionOS.", - "Dependencies": [ - "HyperionOS" - ], - "Tar": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm/tar/HyperionOS-kernel.tar.gz" -} diff --git a/spm/pkg/HyperionOS-units.pkg b/spm/pkg/HyperionOS-units.pkg deleted file mode 100644 index 4c72314..0000000 --- a/spm/pkg/HyperionOS-units.pkg +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Name": "HyperionOS unit tests", - "Version": "1.0.0", - "Publishers": ["HyperionOS Dev Team"], - "Description": "HyperionOS testing units", - "Dependencies": [ - "HyperionOS" - ], - "Tar": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm/tar/HyperionOS-units.tar.gz" -} \ No newline at end of file diff --git a/spm/pkg/HyperionOS.pkg b/spm/pkg/HyperionOS.pkg deleted file mode 100644 index 4260c66..0000000 --- a/spm/pkg/HyperionOS.pkg +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Name": "HyperionOS", - "Version": "1.0.0", - "Publishers": ["HyperionOS Dev Team"], - "Description": "The install package for HyperionOS project.", - "Dependencies": [ - "HyperionOS-kernel", - "HyperionOS-core" - ] -} \ No newline at end of file diff --git a/spm/spm.src b/spm/spm.src deleted file mode 100644 index c8bf045..0000000 --- a/spm/spm.src +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Packages":{ - "HyperionOS":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm/pkg/HyperionOS.pkg", - "HyperionOS-core":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm/pkg/HyperionOS-core.pkg", - "HyperionOS-kernel":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm/pkg/HyperionOS-kernel.pkg", - "HyperionOS-firmware-cct":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm/pkg/HyperionOS-firmware-cct.pkg", - "HyperionOS-firmware-oc":"https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm/pkg/HyperionOS-firmware-oc.pkg" - }, - "Nodes":[ - "https://git.astronand.dev/Astronand/HyperionOS-packages/raw/branch/main/spm.src" - ], - "Blacklist":[] -} \ No newline at end of file -- 2.55.0 From 59e09a5995311392dd3f761527f97aac6eb31397 Mon Sep 17 00:00:00 2001 From: Astronand Date: Thu, 26 Mar 2026 10:34:00 -0400 Subject: [PATCH 2/6] Update LICENSE --- LICENSE | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 198 insertions(+), 14 deletions(-) diff --git a/LICENSE b/LICENSE index 1e72e8e..d645695 100644 --- a/LICENSE +++ b/LICENSE @@ -1,18 +1,202 @@ -MIT License -Copyright (c) 2025 Astronand + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -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: + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -The above copyright notice and this permission notice shall be included in all copies or substantial -portions of the Software. + 1. Definitions. -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" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -- 2.55.0 From f7b64c11b71e74356fae910608a82ef4ca168d3c Mon Sep 17 00:00:00 2001 From: Astronand Date: Wed, 27 May 2026 17:01:26 -0400 Subject: [PATCH 3/6] added seperate input and working on http / sockets --- Src/Hyperion-core/data/lib/http | 201 ++ .../data/boot/cct/initdisks | 2 +- .../data/lib/modules/cc-tweaked/22_http.kmod | 305 ++ .../data/lib/modules/cc-tweaked/25_tty.kmod | 36 +- .../lib/modules/cc-tweaked/30_deamon.kmod | 11 +- Src/Hyperion-kernel/data/boot/fstab | 2 +- Src/Hyperion-kernel/data/boot/kernel.lua | 73 +- Src/Hyperion-kernel/data/boot/safeboot.cfg | 2 +- .../data/lib/modules/hyperion/01_stdlib.kmod | 17 + .../data/lib/modules/hyperion/10_vfs.kmod | 96 +- .../data/lib/modules/hyperion/11_ld.kmod | 63 + .../data/lib/modules/hyperion/11_require.kmod | 40 - .../data/lib/modules/hyperion/12_devfs.kmod | 80 +- .../data/lib/modules/hyperion/12_procfs.kmod | 3 +- .../data/lib/modules/hyperion/12_tmpfs.kmod | 233 +- .../data/lib/modules/hyperion/19_fstab.kmod | 3 +- .../data/lib/modules/hyperion/20_socket.kmod | 223 +- .../data/lib/modules/hyperion/30_vterm.kmod | 129 + .../lib/modules/hyperion/45_hypervisor.kmod | 81 +- .../data/lib/modules/hyperion/90_kgc.kmod | 11 + Src/{hysh => coreutils}/data/bin/login | 2 +- Src/{hysh => coreutils}/data/bin/lsusers | 0 Src/{hysh => coreutils}/data/bin/mount | 0 Src/{hysh => coreutils}/data/bin/passwd | 0 Src/{hysh => coreutils}/data/bin/su | 0 Src/{hysh => coreutils}/data/bin/sudo | 0 Src/{hysh => coreutils}/data/bin/umount | 0 Src/{hysh => coreutils}/data/bin/useradd | 0 Src/{hysh => coreutils}/data/bin/userdel | 0 Src/{hysh => coreutils}/data/bin/usermod | 0 Src/hysh/control/symlinks.json | 3 + Src/hysh/data/bin/help | 1 + Src/hysh/data/bin/hysh | 18 +- Src/hysh/data/bin/tree | 113 + Src/installer/data/bin/hyperion-build | 0 Src/installer/data/bin/install | 0 Src/minify/data/bin/minify | 29 + Src/minify/data/lib/minify.lua | 3106 +++++++++++++++++ Src/pid/data/lib/pid.lua | 136 + Src/sysinit/control/symlinks.json | 3 + Src/sysinit/data/usr/lib/sysinit/sysinit | 2 + build.py | 541 +-- docs/kernel/boot.cfg.md | 3 + 43 files changed, 5035 insertions(+), 533 deletions(-) create mode 100644 Src/Hyperion-kernel/data/lib/modules/hyperion/11_ld.kmod delete mode 100644 Src/Hyperion-kernel/data/lib/modules/hyperion/11_require.kmod create mode 100644 Src/Hyperion-kernel/data/lib/modules/hyperion/30_vterm.kmod create mode 100644 Src/Hyperion-kernel/data/lib/modules/hyperion/90_kgc.kmod rename Src/{hysh => coreutils}/data/bin/login (98%) rename Src/{hysh => coreutils}/data/bin/lsusers (100%) rename Src/{hysh => coreutils}/data/bin/mount (100%) rename Src/{hysh => coreutils}/data/bin/passwd (100%) rename Src/{hysh => coreutils}/data/bin/su (100%) rename Src/{hysh => coreutils}/data/bin/sudo (100%) rename Src/{hysh => coreutils}/data/bin/umount (100%) rename Src/{hysh => coreutils}/data/bin/useradd (100%) rename Src/{hysh => coreutils}/data/bin/userdel (100%) rename Src/{hysh => coreutils}/data/bin/usermod (100%) create mode 100644 Src/hysh/control/symlinks.json create mode 100644 Src/hysh/data/bin/tree create mode 100644 Src/installer/data/bin/hyperion-build create mode 100644 Src/installer/data/bin/install create mode 100644 Src/minify/data/bin/minify create mode 100644 Src/minify/data/lib/minify.lua create mode 100644 Src/pid/data/lib/pid.lua create mode 100644 Src/sysinit/control/symlinks.json diff --git a/Src/Hyperion-core/data/lib/http b/Src/Hyperion-core/data/lib/http index e69de29..d313a9a 100644 --- a/Src/Hyperion-core/data/lib/http +++ b/Src/Hyperion-core/data/lib/http @@ -0,0 +1,201 @@ +--:Minify:-- +local http = {} + +local syscall = syscall + +local function parseUrl(url) + local proto, host, path = + url:match( + "^(https?://)([^/]+)(/.*)$" + ) + + if not proto then + proto, host = + url:match( + "^(https?://)([^/]+)$" + ) + + path = "/" + end + + if not proto then + return nil, "EINVAL" + end + + return host, path +end + +local function buildRequest(req) + local host, path = + parseUrl(req.url) + + if not host then + return nil, path + end + + local method = + req.method or "GET" + + local body = + req.body or "" + + local headers = + table.deepcopy( + req.headers or {} + ) + + headers.Host = + headers.Host or host + + headers.Connection = + headers.Connection or "close" + + if body ~= "" then + headers["Content-Length"] = + tostring(#body) + end + + local out = { + method .. + " " .. + path .. + " HTTP/1.1" + } + + for k, v in pairs(headers) do + out[#out + 1] = + tostring(k) .. + ": " .. + tostring(v) + end + + out[#out + 1] = "" + out[#out + 1] = body + + return table.concat(out, "\r\n") +end + +local function parseResponse(raw) + local headerEnd = + raw:find( + "\r\n\r\n", + 1, + true + ) + + if not headerEnd then + return nil, "EBADMSG" + end + + local headerPart = + raw:sub(1, headerEnd - 1) + + local body = + raw:sub(headerEnd + 4) + + local lines = {} + + for line in headerPart:gmatch("[^\r\n]+") do + lines[#lines + 1] = line + end + + local _, code, msg = + lines[1]:match( + "^(HTTP/%S+)%s+(%d+)%s*(.*)$" + ) + + local headers = {} + + for i = 2, #lines do + local k, v = + lines[i]:match( + "^([^:]+):%s*(.*)$" + ) + + if k then + headers[k:lower()] = v + end + end + + return { + code = tonumber(code), + message = msg, + headers = headers, + body = body + } +end + +local function readAll(fd) + local out = "" + + while true do + local chunk = + syscall.read(fd, 4096) + + if not chunk or chunk == "" then + break + end + + out = out .. chunk + end + + return out +end + +function http.request(req) + local raw, err = + buildRequest(req) + + if not raw then + return nil, err + end + + local fd = + syscall.socket(0, 0) + + if not fd then + return nil, "ESOCKET" + end + + local ok, err = + syscall.connect(fd, req.url) + + if not ok then + syscall.close(fd) + return nil, err + end + + local ok2, err2 = + syscall.write(fd, raw) + + if not ok2 then + syscall.close(fd) + return nil, err2 + end + + local resp = + readAll(fd) + + syscall.close(fd) + + return parseResponse(resp) +end + +function http.get(url, headers) + return http.request({ + url = url, + method = "GET", + headers = headers + }) +end + +function http.post(url, body, headers) + return http.request({ + url = url, + method = "POST", + body = body, + headers = headers + }) +end + +return http \ No newline at end of file diff --git a/Src/Hyperion-firmware-cct/data/boot/cct/initdisks b/Src/Hyperion-firmware-cct/data/boot/cct/initdisks index 1480a0b..84d1ffb 100644 --- a/Src/Hyperion-firmware-cct/data/boot/cct/initdisks +++ b/Src/Hyperion-firmware-cct/data/boot/cct/initdisks @@ -258,7 +258,7 @@ local function refresh() end end end - + local function iter() refresh() local combined = {} diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod index 2e517bd..f35b515 100644 --- a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod @@ -1 +1,306 @@ --:Minify:-- +local kernel = ... + +local handler = {} + +local http = kernel.apis.http + +kernel.cct.httpqueue = kernel.cct.httpqueue or {} +kernel.cct.httpresponse = kernel.cct.httpresponse or {} +kernel.cct.httperror = kernel.cct.httperror or {} + +local function parseRawRequest(raw) + local sepLen = 4 + + local headerEnd = + raw:find("\r\n\r\n", 1, true) + + if not headerEnd then + headerEnd = + raw:find("\n\n", 1, true) + + sepLen = 2 + end + + local headerPart + local body = "" + + if headerEnd then + headerPart = raw:sub(1, headerEnd - 1) + body = raw:sub(headerEnd + sepLen) + else + headerPart = raw + end + + local lines = {} + + for line in headerPart:gmatch("[^\r\n]+") do + lines[#lines + 1] = line + end + + if #lines == 0 then + return nil, "EINVAL" + end + + local method, path = + lines[1]:match("^(%S+)%s+(%S+)") + + if not method or not path then + return nil, "EBADMSG" + end + + local headers = {} + + for i = 2, #lines do + local k, v = + lines[i]:match("^([^:]+):%s*(.*)$") + + if k then + headers[k] = v + end + end + + local host = headers.Host or headers.host + + if not host and not path:match("^https?://") then + return nil, "EHOSTUNREACH" + end + + local url + + if path:match("^https?://") then + url = path + else + url = "http://" .. host .. path + end + + local req = { + url = url, + method = method, + headers = headers + } + + if body ~= "" then + req.body = body + end + + return req +end + +local function buildResponse(resp) + if not resp then + return nil, "EINVAL" + end + + local code, msg = resp.getResponseCode() + + local headers = + resp:getResponseHeaders() + + local body = + resp:readAll() or "" + + local out = { + "HTTP/1.1 " .. + tostring(code) .. + " " .. + tostring(msg) + } + + local hasLength = false + + for k, v in pairs(headers or {}) do + if k:lower() == "content-length" then + hasLength = true + end + + out[#out + 1] = + tostring(k) .. + ": " .. + tostring(v) + end + + if not hasLength then + out[#out + 1] = + "Content-Length: " .. + tostring(#body) + end + + out[#out + 1] = "" + out[#out + 1] = body + + return table.concat(out, "\r\n") +end + +function handler.connect(fd, address) + local fdo = kernel.currentTask.fd[fd] + + if not fdo then + return nil, "EBADF" + end + + fdo.socket.rbuf = "" + fdo.socket.closed = false + fdo.socket.httpid = nil + + fdo.handle.write = function(raw) + local req, err = + parseRawRequest(raw) + + if not req then + return nil, err + end + + local id = + tostring(kernel.uuid()) + + fdo.socket.httpid = id + + kernel.cct.httpqueue[id] = true + + local ok, err = + http.request(req, id) + + if not ok then + kernel.cct.httpqueue[id] = nil + return nil, err + end + + return true + end + + fdo.handle.read = function(count) + count = count or 4096 + + local sock = fdo.socket + + if #sock.rbuf > 0 then + local out = + sock.rbuf:sub(1, count) + + sock.rbuf = + sock.rbuf:sub(count + 1) + + return out + end + + local id = sock.httpid + + if not id then + return "" + end + + local function finish(resp) + sock.rbuf = + buildResponse(resp) or "" + + local out = + sock.rbuf:sub(1, count) + + sock.rbuf = + sock.rbuf:sub(count + 1) + + return out + end + + if kernel.cct.httpresponse[id] then + local resp = + kernel.cct.httpresponse[id] + + kernel.cct.httpresponse[id] = nil + kernel.cct.httpqueue[id] = nil + + return finish(resp) + end + + if kernel.cct.httperror[id] then + local err = + kernel.cct.httperror[id] + + kernel.cct.httperror[id] = nil + kernel.cct.httpqueue[id] = nil + + return nil, err + end + + kernel.currentTask.status = "D" + + local coro + + coro = function() + if kernel.cct.httpresponse[id] then + local resp = + kernel.cct.httpresponse[id] + + kernel.cct.httpresponse[id] = nil + kernel.cct.httpqueue[id] = nil + + kernel.asyncReturn( + finish(resp) + ) + + return + end + + if kernel.cct.httperror[id] then + local err = + kernel.cct.httperror[id] + + kernel.cct.httperror[id] = nil + kernel.cct.httpqueue[id] = nil + + kernel.asyncReturn( + nil, + err + ) + + return + end + + coroutine.yield() + end + + kernel.currentTask.ksh = + coroutine.create(function() + local ok, err = + xpcall( + coro, + debug.traceback + ) + + if not ok then + kernel.asyncReturn( + nil, + err + ) + end + end) + end + + fdo.handle.close = function() + fdo.socket.closed = true + + local id = + fdo.socket.httpid + + if id then + kernel.cct.httpqueue[id] = nil + kernel.cct.httpresponse[id] = nil + kernel.cct.httperror[id] = nil + end + + return true + end + + return true +end + +kernel.socket.registerProtocal( + "http://", + handler +) + +kernel.socket.registerProtocal( + "https://", + handler +) \ No newline at end of file diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod index e690425..f560b6e 100644 --- a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod @@ -223,6 +223,9 @@ local function newtty(obj, id, ev) gctrl=function() return serializeBool(kernel.cct.ctrl)..";"..serializeBool(kernel.cct.alt) end, + isvirt=function() + return false + end, gplt=function() return plt end @@ -243,8 +246,39 @@ end local fifo = kernel.newFifo() kernel.cct.fifo=fifo -newtty(kernel.apis.term, "1", fifo.pop) +newtty(kernel.apis.term, "1", function() end) for i,v in ipairs({peripheral.find("monitor")}) do newtty(v,tostring(i+1),function () end) +end + +kernel.devfs.data["input"]["keyboard1"] = function(op, mode) + if op=="type" then + return "Keyboard" + elseif op=="open" then + local h = { + read=function(amount) + local rv="" + for i=1, amount or 1 do + local event = {fifo.pop()} + if event[1] then + rv=rv..event[1] + end + end + if rv=="" then rv=nil end + return rv + end, + write=function(content) + end + } + if mode=="rw" then + return h + elseif mode=="r" then + h["write"]=nil + return h + elseif mode=="w" then + h["read"]=nil + return h + end + end end \ No newline at end of file diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_deamon.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_deamon.kmod index f3d4acc..551a274 100644 --- a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_deamon.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_deamon.kmod @@ -4,6 +4,7 @@ local keys=kernel.apis.keys kernel.processes.cctdeamon = function() local timeout = false + kernel.log("CCT deamon started") while true do local event = {kernel.EFI:getMachineEvent()} @@ -66,6 +67,12 @@ kernel.processes.cctdeamon = function() elseif eventType == "keyTyped" then if charOrKey then kernel.cct.fifo.push(charOrKey) end + elseif eventType == "mouse_scroll" then + if event[2] == 1 then + kernel.cct.fifo.push("S") + else + kernel.cct.fifo.push("T") + end elseif eventType == "http_success" then kernel.cct.httpqueue[event[2]]=nil kernel.cct.httpresponse[event[2]]=event[3] @@ -83,4 +90,6 @@ kernel.processes.cctdeamon = function() sleep(0.05) end end -end \ No newline at end of file +end + +kernel.log("CCT deamon queued for execution") \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/boot/fstab b/Src/Hyperion-kernel/data/boot/fstab index 0f7573d..cce912b 100644 --- a/Src/Hyperion-kernel/data/boot/fstab +++ b/Src/Hyperion-kernel/data/boot/fstab @@ -1,4 +1,4 @@ U $;/ U devfs0000;/dev/ U tmpfs0000;/tmp/ -U procfs0000;/proc/ \ No newline at end of file +U procfs0000;/proc/ diff --git a/Src/Hyperion-kernel/data/boot/kernel.lua b/Src/Hyperion-kernel/data/boot/kernel.lua index 3286917..d5afe4e 100644 --- a/Src/Hyperion-kernel/data/boot/kernel.lua +++ b/Src/Hyperion-kernel/data/boot/kernel.lua @@ -19,26 +19,34 @@ kernel.status = "start" kernel.key = {} kernel.cache = {} kernel.cache.preload = {} +kernel.unixSockets={} kernel._G=_G kernel.sleep=sleep _G.sleep=nil -local windowsExp = true +local windowsExp = false -function kernel.log(msg, level, c) - c=c or 0x6D6D6D - kernel.LOG_Text = kernel.LOG_Text..tostring(EFI:date()).." "..kernel.users[kernel.uid].." "..kernel.process.."["..tostring(level or "INFO").."]: "..msg.."\n" - if kernel.status == "start" then - screen:setTextColor(c) - screen:print(tostring(EFI:date()).." "..kernel.users[kernel.uid].." "..kernel.process.."["..tostring(level or "INFO").."]: "..msg) - elseif kernel.status == "term" then - kernel.standbyTask=kernel.currentTask - kernel.currentTask=kernel.kernelTask - local file=kernel.vfs.open("/dev/console", "w") - kernel.vfs.devctl(file,"sfgc",c) - kernel.vfs.write(file,tostring(EFI:date()).." "..kernel.users[kernel.uid].." "..kernel.process.."["..tostring(level or "INFO").."]: "..msg.."\n") - kernel.vfs.close(file) - kernel.currentTask=kernel.standbyTask +function kernel.log(msg, level, c, nopanic) + local f=function() + c=c or 0x6D6D6D + kernel.LOG_Text = kernel.LOG_Text..tostring(EFI:date()).." "..kernel.users[kernel.uid].." "..kernel.process.."["..tostring(level or "INFO").."]: "..msg.."\n" + if kernel.status == "start" then + screen:setTextColor(c) + screen:print(tostring(EFI:date()).." "..kernel.users[kernel.uid].." "..kernel.process.."["..tostring(level or "INFO").."]: "..msg) + elseif kernel.status == "term" then + kernel.standbyTask=kernel.currentTask + kernel.currentTask=kernel.kernelTask + local file=kernel.vfs.open("/dev/console", "w") + kernel.vfs.devctl(file,"sfgc",c) + kernel.vfs.write(file,tostring(EFI:date()).." "..kernel.users[kernel.uid].." "..kernel.process.."["..tostring(level or "INFO").."]: "..msg.."\n") + kernel.vfs.close(file) + kernel.currentTask=kernel.standbyTask + end + end + + local ok,err = xpcall(f,debug.traceback) + if not ok and not nopanic then + kernel.panic(err) end end @@ -246,6 +254,15 @@ function kernel.reboot() kernel.status="reboot" end +function kernel.halt() + kernel.exitMain=true + kernel.status="halt" +end + +function kernel.asyncReturn(...) + kernel.currentTask.syscallReturn = {...} +end + kernel.syscalls["time"]=function() return kernel.EFI:getEpochMs() end kernel.syscalls["date"]=function() return kernel.EFI:date() end kernel.syscalls["log"]=kernel.log @@ -264,8 +281,21 @@ kernel.syscalls["sysdump"]=function() end return rv end -kernel.syscalls["reboot"]=kernel.reboot -kernel.syscalls["shutdown"]=kernel.shutdown +kernel.syscalls["reboot"]=function() + if kernel.uid==0 or kernel.groups.wheel then + kernel.reboot() + end +end +kernel.syscalls["shutdown"]=function() + if kernel.uid==0 or kernel.groups.wheel then + kernel.shutdown() + end +end +kernel.syscalls["halt"]=function() + if kernel.uid==0 or kernel.groups.wheel then + kernel.halt() + end +end kernel.log("Running modules") for _,p in ipairs(modules) do @@ -287,11 +317,18 @@ kernel.log("Kernel initialized successfully.") kernel.saveLog() kernel.status="running" screen:disable() -kernel.main() +local ok,err = xpcall(kernel.main, debug.traceback) +if not ok then + kernel.panic(err) +end if kernel.status=="panic" then kernel.panic(kernel.reason) end if kernel.status=="reboot" then EFI.reboot=true return true +elseif kernel.status=="halt" then + kernel.log("System halted.") + kernel.saveLog() + while true do end end \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/boot/safeboot.cfg b/Src/Hyperion-kernel/data/boot/safeboot.cfg index 8005543..b079c61 100644 --- a/Src/Hyperion-kernel/data/boot/safeboot.cfg +++ b/Src/Hyperion-kernel/data/boot/safeboot.cfg @@ -7,5 +7,5 @@ return { initPath = "/sbin/init", maxOpenFiles = 128, maxFilesPerTask = 16, - preempt=true + preempt = true, } \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod index 0c0420a..b4ec413 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod @@ -229,6 +229,23 @@ function toHex(num) return string.format("%X", num) end +local st={ + push=function(self,...) table.insert(self.contents,{...}) end, + pop=function(self) return table.unpack(table.remove(self.contents)) end, +} +local q={ + push=function(self,...) table.insert(self.contents,{...}) end, + pop=function(self) return table.unpack(table.remove(self.contents,1)) end, +} + +function stack() + return setmetatable({contents={}}, {__index=st}) +end + +function queue() + return setmetatable({contents={}}, {__index=q}) +end + local function makeSyscallProxy() local backing = {} return setmetatable(backing, { diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod index 2aa8be6..800cd89 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod @@ -542,6 +542,7 @@ local function allocFD(task) if fd >= kernel.config.maxFilesPerTask then error("ENFILE") end return fd end + local function checkSystemLimit() if total >= kernel.config.maxOpenFiles - 16 then error("ENFILE") end end @@ -555,27 +556,88 @@ function vfs.newfd(fdobj) return fd end -function vfs.mount(target, diskOrId) +function vfs.mount(target, diskOrId, bind) local _euid = (kernel.currentTask and (kernel.currentTask.euid or kernel.currentTask.uid)) or kernel.uid if _euid ~= 0 then error("EPERM") end if not target then error("EINVAL") end target = normalizeMountPoint(target) local drive, path = resolvePath(target) - if not drive:directoryExists(path) then drive:makeDirectory(path) end - if drive:type(target) ~= "directory" then error("EINVAL") end - + if not drive:directoryExists(path) then + drive:makeDirectory(path) + end + if drive:type(path) ~= "directory" then + error("EINVAL") + end local disk, id - if type(diskOrId) == "string" then - disk = kernel.disks[diskOrId] - if not disk then error("ENODEV") end - checkDisk(disk); id = diskOrId - elseif type(diskOrId) == "table" then - checkDisk(diskOrId); disk = diskOrId - id = disk.address; vfs.disks[id] = disk - else error("EINVAL") end - + -- bind mount + if bind then + local src = normalizeMountPoint(diskOrId) + local srcDrive = resolvePath(src) + if not srcDrive then error("ENOENT") end + id = "bind:" .. src + disk = { + address = id, + isBind = true, + source = srcDrive, + exists = function(_, p) + return srcDrive:exists(p) + end, + type = function(_, p) + return srcDrive:type(p) + end, + list = function(_, p) + return srcDrive:list(p) + end, + open = function(_, ...) + return srcDrive:open(...) + end, + remove = function(_, p) + return srcDrive:remove(p) + end, + makeDirectory = function(_, p) + return srcDrive:makeDirectory(p) + end, + rename = function(_, a, b) + return srcDrive:rename(a, b) + end, + size = function(_, p) + return srcDrive:size(p) + end, + lastModified = function(_, p) + return srcDrive:lastModified(p) + end, + isReadOnly = function() + return srcDrive:isReadOnly() + end, + spaceTotal = function() + return srcDrive:spaceTotal() + end, + spaceUsed = function() + return srcDrive:spaceUsed() + end + } + vfs.disks[id] = disk + else + if type(diskOrId) == "string" then + disk = vfs.disks[diskOrId] + if not disk then error("ENODEV") end + checkDisk(disk) + id = diskOrId + elseif type(diskOrId) == "table" then + checkDisk(diskOrId) + disk = diskOrId + id = disk.address + vfs.disks[id] = disk + else + error("EINVAL") + end + end if vfs.mounts[id] then error("EBUSY") end - for _, mp in pairs(vfs.mounts) do if mp == target then error("EBUSY") end end + for _, mp in pairs(vfs.mounts) do + if mp == target then + error("EBUSY") + end + end vfs.mounts[id] = target return true end @@ -588,7 +650,11 @@ function vfs.umount(target) for id, mp in pairs(vfs.mounts) do if mp == target then if id == "$" then error("EBUSY") end - vfs.mounts[id] = nil; return true + vfs.mounts[id] = nil + if vfs.disks[id] and vfs.disks[id].isBind then + vfs.disks[id] = nil + end + return true end end error("EINVAL") diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/11_ld.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/11_ld.kmod new file mode 100644 index 0000000..302edf0 --- /dev/null +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/11_ld.kmod @@ -0,0 +1,63 @@ +--:Minify:-- +local kernel = ... +local cache = {} +kernel.searchpaths = { + "?", "?.lua", "/lib/?", "/lib/?.lua", "/usr/lib/?", "/usr/lib/?.lua", + "/usr/local/lib/?", "/usr/local/lib/?.lua" +} +kernel.reqcache = cache + +local function require(module, ...) + if cache[module] then return cache[module].ret end + kernel.currentTask.status = "D" + local args = {...} + kernel.currentTask.ksh = coroutine.create(function() + local coro = function() + for _, path in ipairs(kernel.searchpaths) do + local filepath = path:gsub("?", module) + if kernel.vfs.exists(filepath) then + if kernel.vfs.type(filepath) == "directory" then + filepath = filepath .. "/init.lua" + if kernel.vfs.type(filepath) == "directory" then + kernel.asyncReturn(false, "Module not found: "..module) + return + end + end + + local fd = kernel.vfs.open(filepath, "r") + local chunks = {} + while true do + local chunk = kernel.vfs.read(fd, 4096) + if not chunk or chunk == "" then break end + chunks[#chunks + 1] = chunk + coroutine.yield() + end + kernel.vfs.close(fd) + local data = table.concat(chunks) + local func, err = load(data, "@"..module, "t", kernel._U) + if not func then + kernel.asyncReturn(false, "Error loading module "..module..": "..tostring(err)) + return + end + local ok, ret = xpcall(func, debug.traceback, table.unpack(args)) + if not ok then + kernel.asyncReturn(false, "Error running module "..module..": "..tostring(ret)) + return + end + cache[module] = {ret = ret, expires = kernel.EFI:getEpochMs() + 120000} + kernel.asyncReturn(true, ret) + return + end + coroutine.yield() + end + kernel.asyncReturn(false, "Module not found: "..module) + end + local status, err = xpcall(coro, debug.traceback) + if not status then + kernel.asyncReturn(false, "Error in require coroutine for module "..module..": "..tostring(err)) + end + end) +end + +kernel.syscalls["require"] = require +_G.require = function(...) return syscall.require(...) end \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/11_require.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/11_require.kmod deleted file mode 100644 index 7068837..0000000 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/11_require.kmod +++ /dev/null @@ -1,40 +0,0 @@ ---:Minify:-- -local kernel = ... -local cache = {} -kernel.searchpaths = { - "/lib/?.lua", "/lib/?", "/usr/lib/?.lua", "/usr/lib/?", - "/usr/local/lib/?.lua", "/usr/local/lib/?", "?.lua", "?" -} - -function require(module, ...) - if cache[module] then return cache[module] end - local modpath = module:gsub("%.", "/") - local failed = {} - for _, path in ipairs(kernel.searchpaths) do - local full_path = string.replace(path, "?", modpath) - if full_path:sub(1, 1) ~= "/" then - full_path = kernel.currentTask.cwd .. full_path - end - - if kernel.vfs.exists(full_path) then - if kernel.vfs.type(full_path) == "directory" then - full_path = full_path .. "/init" - end - - if kernel.vfs.exists(full_path) then - local handle = kernel.vfs.open(full_path, "r") - local file_content = kernel.vfs.read(handle, 1024 * 1024 * 4) - kernel.vfs.close(handle) - - return - assert(load(file_content, full_path, "t", kernel._U))(...) - else - table.insert(failed, full_path) - end - else - table.insert(failed, full_path) - end - end - - error("Module not found: " .. module .. " (searched paths: " .. table.concat(failed, ", ") .. ")") -end diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod index be427d5..12121f0 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod @@ -140,6 +140,83 @@ function data.zero(op, mode) end end +local function buildMeta(entries, opts) + opts = opts or {} + local uid = opts.uid or 0 + local gid = opts.gid or 0 + local perms = opts.perms or 0x3F -- default read/write for owner/group/world + + local chunks = {} + table.insert(chunks, string.char(0x02)) -- version header + + for path, target in pairs(entries) do + local name = path + local nameLen = #name + if nameLen > 255 then + error("Filename too long (>255 bytes): "..name) + end + + -- Determine entry type: 0x01 = symlink if target ~= nil and target ~= "" + local entryType = 0x00 + local cmeta = "" + if target and target ~= "" then + entryType = 0x01 + cmeta = target + end + local cmetaLen = #cmeta + if cmetaLen > 255 then + error("cmeta too long (>255 bytes) for "..name) + end + + -- Build entry as bytes + table.insert(chunks, string.char(nameLen)) -- name length + table.insert(chunks, name) -- name + table.insert(chunks, string.char(entryType)) -- entry type + table.insert(chunks, string.char(uid % 256, math.floor(uid/256) % 256)) -- uid + table.insert(chunks, string.char(gid % 256, math.floor(gid/256) % 256)) -- gid + table.insert(chunks, string.char(perms % 256, math.floor(perms/256) % 256)) -- perms + table.insert(chunks, string.char(cmetaLen)) -- cmeta length + if cmetaLen > 0 then + table.insert(chunks, cmeta) + end + end + + return table.concat(chunks) +end + +local function simpleFile(r,w) + return function(op, mode) + if op=="type" then + return "file" + elseif op=="open" then + if mode=="r" then + return { + read=r + } + elseif mode=="w" then + return { + write=w + } + end + end + end +end + +local function strFile(str) + local dat=tostring(str) + local pos=1 + return simpleFile(function(amount) + pos=pos+amount + return dat:sub(pos-amount, pos) + end,function() error("EACCES") end) +end + +data[".meta"]=strFile(buildMeta({ + stdin="/proc/self/fd/0", + stdout="/proc/self/fd/1", + log="/var/log/syslog.log" +})) + if kernel.EFI:getEEPROM() then function data.eeprom(op, mode) if op=="type" then @@ -216,7 +293,8 @@ if kernel.EFI:getNvram() then end end -data["disk"]={} +data["disk"]={["by-id"]={}, ["by-path"]={}, ["by-label"]={}} +data["input"]={} kernel.devfs={} kernel.devfs.data=data kernel.devfs.proxy=proxy diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/12_procfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_procfs.kmod index 028c343..2ead312 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/12_procfs.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_procfs.kmod @@ -114,7 +114,8 @@ local function newtaskproxy(task) }, children={ [".meta"]=strFile(buildMeta(children)) - } + }, + pid=strFile(task.pid) } end diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/12_tmpfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_tmpfs.kmod index eecb14f..96d4517 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/12_tmpfs.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_tmpfs.kmod @@ -1,134 +1,141 @@ --:Minify:-- local kernel = ... -local proxy = {} -local data = {} +kernel.vfs.remove("/tmp") +kernel.vfs.mkdir("/tmp") +if not kernel.config.tmpToDisk then + local proxy = {} + local data = {} -proxy.address = "tmpfs0000" -proxy.isvirt = true -proxy.isReadOnly = function() return false end + proxy.address = "tmpfs0000" + proxy.isvirt = true + proxy.isReadOnly = function() return false end -proxy.spaceUsed = function() return 0 end -proxy.spaceTotal = function() return 0 end + proxy.spaceUsed = function() return 0 end + proxy.spaceTotal = function() return 0 end -proxy.makeDirectory = function(_, path) - local steps = kernel.vfs.splitPath(path) - local step = data - for i=1,#steps do - if not step[steps[i]] then - step[steps[i]] = {} - elseif type(step[steps[i]]) ~= "table" then - error("ENOTDIR") + proxy.makeDirectory = function(_, path) + local steps = kernel.vfs.splitPath(path) + local step = data + for i=1,#steps do + if not step[steps[i]] then + step[steps[i]] = {} + elseif type(step[steps[i]]) ~= "table" then + error("ENOTDIR") + end + step = step[steps[i]] end - step = step[steps[i]] end -end -proxy.remove = function(_, path) - local steps = kernel.vfs.splitPath(path) - local step = data - for i=1,#steps-1 do - step = step[steps[i]] - if not step then error("ENOENT") end - end - step[steps[#steps]] = nil -end - -proxy.setLabel = function(_, label) end -proxy.getLabel = function() return "tmpfs" end - -proxy.attributes = function(_, path) - local steps = kernel.vfs.splitPath(path) - local step = data - for i=1,#steps do - step = step[steps[i]] - if not step then error("ENOENT") end - end - return { - size = type(step) == "string" and #step or 0, - modified = 0, - created = 0, - } -end - -function proxy:open(path, mode) - local steps = kernel.vfs.splitPath(path) - local step = data - for i=1,#steps-1 do - if not step[steps[i]] then - if mode == "w" then step[steps[i]] = {} else error("ENOENT") end - elseif type(step[steps[i]]) ~= "table" then - error("ENOTDIR") + proxy.remove = function(_, path) + local steps = kernel.vfs.splitPath(path) + local step = data + for i=1,#steps-1 do + step = step[steps[i]] + if not step then error("ENOENT") end end - step = step[steps[i]] + step[steps[#steps]] = nil end - local filename = steps[#steps] - if mode == "r" then - if type(step[filename]) ~= "string" then error("ENOENT") end - local content = step[filename] - local pos = 1 + proxy.setLabel = function(_, label) end + proxy.getLabel = function() return "tmpfs" end + + proxy.attributes = function(_, path) + local steps = kernel.vfs.splitPath(path) + local step = data + for i=1,#steps do + step = step[steps[i]] + if not step then error("ENOENT") end + end return { - read = function(amount) - amount = amount or #content - local chunk = content:sub(pos, pos+amount-1) - pos = pos + #chunk - return chunk - end, - close = function() end, + size = type(step) == "string" and #step or 0, + modified = 0, + created = 0, } - elseif mode == "w" then - step[filename] = "" - local buf = {} - return { - write = function(str) - buf[#buf + 1] = str - end, - close = function() - step[filename] = table.concat(buf) - end, - } - elseif mode == "a" then - if type(step[filename]) ~= "string" then step[filename] = "" end - return { - write = function(str) - step[filename] = step[filename] .. str - end, - close = function() end, - } - else - error("EACCES") end -end -function proxy:type(path) - local steps = kernel.vfs.splitPath(path) - local step = data - if #steps == 0 then return "directory" end - for i=1,#steps do - step = step[steps[i]] - if not step then return false end + function proxy:open(path, mode) + local steps = kernel.vfs.splitPath(path) + local step = data + for i=1,#steps-1 do + if not step[steps[i]] then + if mode == "w" then step[steps[i]] = {} else error("ENOENT") end + elseif type(step[steps[i]]) ~= "table" then + error("ENOTDIR") + end + step = step[steps[i]] + end + local filename = steps[#steps] + + if mode == "r" then + if type(step[filename]) ~= "string" then error("ENOENT") end + local content = step[filename] + local pos = 1 + return { + read = function(amount) + amount = amount or #content + local chunk = content:sub(pos, pos+amount-1) + pos = pos + #chunk + return chunk + end, + close = function() end, + } + elseif mode == "w" then + step[filename] = "" + local buf = {} + return { + write = function(str) + buf[#buf + 1] = str + end, + close = function() + step[filename] = table.concat(buf) + end, + } + elseif mode == "a" then + if type(step[filename]) ~= "string" then step[filename] = "" end + return { + write = function(str) + step[filename] = step[filename] .. str + end, + close = function() end, + } + else + error("EACCES") + end end - if type(step) == "table" then return "directory" end - if type(step) == "string" then return "file" end -end -function proxy:list(path) - local steps = kernel.vfs.splitPath(path) - local step = data - for i=1,#steps do - step = step[steps[i]] - if not step then error("ENOENT") end + function proxy:type(path) + local steps = kernel.vfs.splitPath(path) + local step = data + if #steps == 0 then return "directory" end + for i=1,#steps do + step = step[steps[i]] + if not step then return false end + end + if type(step) == "table" then return "directory" end + if type(step) == "string" then return "file" end end - if type(step) ~= "table" then error("ENOTDIR") end - local keys = {} - for k,_ in pairs(step) do table.insert(keys, k) end - return keys -end -function proxy:fileExists(path) - local t = self:type(path) - return t == "file" or t == "directory" -end + function proxy:list(path) + local steps = kernel.vfs.splitPath(path) + local step = data + for i=1,#steps do + step = step[steps[i]] + if not step then error("ENOENT") end + end + if type(step) ~= "table" then error("ENOTDIR") end + local keys = {} + for k,_ in pairs(step) do table.insert(keys, k) end + return keys + end -kernel.disks["tmpfs0000"] = proxy \ No newline at end of file + function proxy:fileExists(path) + local t = self:type(path) + return t == "file" or t == "directory" + end + + kernel.disks["tmpfs0000"] = proxy +else + kernel.log("tmpToDisk enabled, skipping tmpfs module") + kernel.log("tmpfs0000 will passthrough to /tmp on the disk") +end \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/19_fstab.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/19_fstab.kmod index 9034cea..50bdc8e 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/19_fstab.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/19_fstab.kmod @@ -25,10 +25,11 @@ for _, line in ipairs(string.split(kernel.fstab, "\n")) do else local id = line:sub(3, semicolon_pos - 1) local path = trim(line:sub(semicolon_pos + 1)) - kernel.log("Mounted "..id.." to "..path) + kernel.log("Mounting '"..id.."' to '"..path.."'") if id ~= "$" then kernel.vfs.mount(path, id) end + kernel.log("Mounted "..id.." to "..path) end end end \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod index 18e280a..cf70b3c 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod @@ -1,67 +1,194 @@ --:Minify:-- --- Supports: --- AF_UNIX - local IPC via /var/run/*.sock paths --- AF_INET - network sockets with three backends: --- Implemented by drivers but expect http:// and https:// --- --- Socket lifecycle: --- fd = syscall.socket(domain, socktype) -- "unix"/"inet", "stream"/"dgram" --- syscall.bind(fd, address) -- server: claim address --- syscall.listen(fd, backlog) -- server: mark as listening --- cfd = syscall.accept(fd) -- server: get connected client fd (blocking poll) --- syscall.connect(fd, address) -- client: connect to server --- syscall.send(fd, data) -- send bytes --- syscall.recv(fd, len) -- receive bytes (blocking poll, returns "" on nothing) --- syscall.sockshutdown(fd) -- half-close send side --- -- normal vfs.close(fd) closes the socket +local kernel = ... -local kernel=... -local socket={} -socket.handlers={} -kernel.socket=socket +local socket = {} -function socket.registerProtocal(protocal, handler) - socket.handlers[protocal] = handler +socket.handlers = {} + +kernel.socket = socket + +local P = kernel.vfs.P +local sys = kernel.syscalls + +function socket.registerProtocal(proto, handler) + socket.handlers[proto] = handler end -function socket.socket() - local P=kernel.vfs.P - local data=kernel.newFifo() - local isClosed=false - return kernel.vfs.newfd({ - handle={ - read=function() if isClosed then error("ECCON") end return data.pop() end, - write=function(data) if isClosed then error("ECCON") end return data.push(data) end, - close=function() isClosed = true end +local function getHandler(address) + for proto, handler in pairs(socket.handlers) do + if string.hasPrefix(address, proto) then + return handler + end + end +end + +function socket.socket(domain, socktype) + local fd = kernel.vfs.newfd({ + handle = {}, + + type = "socket", + + refcount = 1, + + socket = { + connected = false, + protocol = nil, + address = nil }, - type="socket", - refcount=1, - socket={}, - meta={ - owner=kernel.currentTask.uid, - group=kernel.currentTask.uid, - etype=2, - perms=P.OWNER_R+P.OWNER_W+P.GROUP_R+P.GROUP_W + + meta = { + owner = kernel.currentTask.uid, + group = kernel.currentTask.uid, + etype = 2, + + perms = + P.OWNER_R + + P.OWNER_W + + P.GROUP_R + + P.GROUP_W }, - isvirt=true + + isvirt = true }) + + local fdo = kernel.currentTask.fd[fd] + + fdo.handle.read = function() + return "" + end + + fdo.handle.write = function() + return nil, "ENOTCONN" + end + + fdo.handle.close = function() + fdo.socket.connected = false + return true + end + + return fd end function socket.connect(fd, address) - local handler - for k, v in pairs(socket.handlers) do - if string.hasPrefix(address, k) then - handler=v - end + local fdo = kernel.currentTask.fd[fd] + + if not fdo then + return nil, "EBADF" end - handler.connect(kernel.currentTask.fd[fd], address) + + if fdo.type ~= "socket" then + return nil, "ENOTSOCK" + end + + local handler = + getHandler(address) + + if not handler then + return nil, "EPROTONOSUPPORT" + end + + fdo.socket.protocol = handler + fdo.socket.address = address + + local ok, err = + handler.connect(fd, address) + + if not ok then + return nil, err + end + + fdo.socket.connected = true + + return true end function socket.listen(fd, backlog) - error("Not Implemented") + local fdo = + kernel.currentTask.fd[fd] + + if not fdo then + return nil, "EBADF" + end + + if not fdo.handle.listen then + return nil, "EOPNOTSUPP" + end + + return fdo.handle.listen(backlog) end -local sys=kernel.syscalls -sys["socket"]=socket.socket +function socket.send(fd, data) + local fdo = + kernel.currentTask.fd[fd] + + if not fdo then + return nil, "EBADF" + end + + if fdo.type ~= "socket" then + return nil, "ENOTSOCK" + end + + if not fdo.socket.connected then + return nil, "ENOTCONN" + end + + if not fdo.handle.write then + return nil, "EOPNOTSUPP" + end + + return fdo.handle.write(data) +end + +function socket.recv(fd, amount) + local fdo = + kernel.currentTask.fd[fd] + + if not fdo then + return nil, "EBADF" + end + + if fdo.type ~= "socket" then + return nil, "ENOTSOCK" + end + + if not fdo.socket.connected then + return nil, "ENOTCONN" + end + + if not fdo.handle.read then + return nil, "EOPNOTSUPP" + end + + return fdo.handle.read(amount) +end + +function socket.sockshutdown(fd) + local fdo = + kernel.currentTask.fd[fd] + + if not fdo then + return nil, "EBADF" + end + + if fdo.type ~= "socket" then + return nil, "ENOTSOCK" + end + + if fdo.handle.close then + return fdo.handle.close() + end + + fdo.socket.connected = false + + return true +end + +sys.socket = socket.socket +sys.connect = socket.connect +sys.listen = socket.listen +sys.send = socket.send +sys.recv = socket.recv +sys.sockshutdown = socket.sockshutdown kernel.log("Loaded socket module") \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/30_vterm.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/30_vterm.kmod new file mode 100644 index 0000000..1ec91b7 --- /dev/null +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/30_vterm.kmod @@ -0,0 +1,129 @@ +--:Minify:-- +local kernel = ... + +local vterms = {} + +local function createVt(id, width, height) + local vt = { + id = id, + width = width, + height = height, + buffer = {}, + cursorX = 1, + cursorY = 1, + fgColor = 0xFFFFFF, + bgColor = 0x000000, + obj = {} + } + + for y = 1, height do + vt.buffer[y] = {} + for x = 1, width do + vt.buffer[y][x] = {char = " ", fgColor = vt.fgColor, bgColor = vt.bgColor} + end + end + + local function scroll(lines) + for _ = 1, lines do + table.remove(vt.buffer, 1) + vt.buffer[vt.height] = {} + for x = 1, vt.width do + vt.buffer[vt.height][x] = {char = " ", fgColor = vt.fgColor, bgColor = vt.bgColor} + end + end + end + + function vt.obj:write(content) + local x, y = vt.cursorX, vt.cursorY + if x>vt.width then return end + if y>vt.height then return end + for i = 1, #content do + local c = content:sub(i, i) + if c == "\n" then + y = y + 1 + x = 1 + elseif c == "\t" then + local tabSize = 4 + local spaces = tabSize - ((x - 1) % tabSize) + for _ = 1, spaces do + vt.buffer[y][x] = {char = " ", fgColor = vt.fgColor, bgColor = vt.bgColor} + x = x + 1 + if x > vt.width then + x = 1 + y = y + 1 + end + end + elseif c == "\b" then + if x > 1 then + x = x - 1 + vt.buffer[y][x] = {char = " ", fgColor = vt.fgColor, bgColor = vt.bgColor} + end + else + if x <= vt.width and y <= vt.height then + vt.buffer[y][x] = {char = c, fgColor = vt.fgColor, bgColor = vt.bgColor} + x = x + 1 + end + end + + if x > vt.width then + x = 1 + y = y + 1 + end + + if y > vt.height then + scroll(1) + y = vt.height + end + end + + vt.cursorX, vt.cursorY = x, y + end + + function vt.obj:spos(x, y) + vt.cursorX = tonumber(x) + vt.cursorY = tonumber(y) + end + + function vt.obj:gpos() + return tostring(vt.cursorX)..";"..tostring(vt.cursorY) + end + + function vt.obj:sfgc(color) + vt.fgColor = tonumber(color) + end + + function vt.obj:sbgc(color) + vt.bgColor = tonumber(color) + end + + function vt.obj:gfgc() + return vt.fgColor + end + + function vt.obj:gbgc() + return vt.bgColor + end + + function vt.obj:gplt() + return 24 + end + + function vt.obj:clear() + for y = 1, vt.height do + for x = 1, vt.width do + vt.buffer[y][x] = {char = " ", fgColor = vt.fgColor, bgColor = vt.bgColor} + end + end + vt.cursorX, vt.cursorY = 1, 1 + end + + function vt.obj:isvirt() + return true + end + + function vt.obj:gctrl() + return serializeBool(vt.ctrl)..";"..serializeBool(vt.alt) + end + + return vt +end \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod index ad4606e..0985a6d 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod @@ -21,7 +21,7 @@ local function loadExecutable(path) local env = kernel.freshUserEnv() local func, err = load(data, "@" .. path, "t", env) - if not func then error("ENOEXEC: " .. tostring(err)) end + if not func then kernel.log("Failed to load executable: " .. tostring(err).. " : ".. tostring(path)); error("ENOEXEC: " .. tostring(err)) end local meta = kernel.vfs.lstat(path) local suid_set = bit_is_set(meta.perms, 6) @@ -211,6 +211,8 @@ function sys.kill(pid, force) return false, "Task is already dead" elseif task.status == "D" and not force then return false, "Cannot kill task waiting for IO" + elseif task.euid ~= kernel.uid and kernel.uid ~= 0 then + return false, "Different user" end local caller = kernel.currentTask local ceuid = caller and (caller.euid or caller.uid) or kernel.uid @@ -227,6 +229,8 @@ function sys.stop(pid) return false, "Task does not exist" elseif task.status ~= "R" and task.status ~= "S" then return false, "Cannot stop non-running task" + elseif task.euid ~= kernel.uid and kernel.uid ~= 0 then + return false, "Different user" else if task.status == "S" then task.status = "ST" @@ -243,6 +247,8 @@ function sys.continue(pid) return false, "Task does not exist" elseif task.status ~= "T" and task.status ~= "ST" then return false, "Task is not stopped" + elseif task.euid ~= kernel.uid and kernel.uid ~= 0 then + return false, "Different user" else if task.status == "ST" then task.status = "S" @@ -299,20 +305,21 @@ function sys.getuid() return kernel.currentTask.uid end local function reapDeadTasks() for pid, task in pairs(tasks) do if task.status == "Z" and not task.reapTime then - task.coro = nil - task.ivs = nil - task.vs = nil - task.args = nil - task.envars = nil - task.cwd = nil - task.numRuns = nil - task.totalTime = nil - task.lastTime = nil - task.timeSlice = nil + if task.pid == 1 then kernel.panic("Attempted to gc init!") end + task.coro = nil + task.ivs = nil + task.vs = nil + task.args = nil + task.envars = nil + task.cwd = nil + task.numRuns = nil + task.totalTime = nil + task.lastTime = nil + task.timeSlice = nil task.syscallReturn = nil - task.sleep = nil - task.fd = nil - task.reapTime = kernel.EFI:getEpochMs() + 30000 + task.sleep = nil + task.fd = nil + task.reapTime = kernel.EFI:getEpochMs() + 30000 elseif task.reapTime and kernel.EFI:getEpochMs() > task.reapTime and task.status == "Z" then @@ -344,7 +351,23 @@ local k_max = 0.5 local B = 0.01 function kernel.main() + kernel.log("Starting main loop...") + kernel.saveLog() + local stopLog=5 + local logTasks=100 + while not kernel.exitMain do + if kernel.config.logTasks then + if logTasks<0 then + kernel.log("Active Tasks:") + for i,v in pairs(tasks) do + kernel.log(v.name.." : "..v.status.." : "..tostring(v.pid).." : "..tostring(v.exit)) + end + kernel.log("[END BLOCK]") + logTasks=100 + end + logTasks=logTasks-1 + end local N = 0 local Tmin_hit = 0 local Tmax_hit = 0 @@ -352,6 +375,7 @@ function kernel.main() local taskTimes = {} for pid, task in pairs(tasks) do + if kernel.exitMain then break end kernel.currentTask = task kernel.uid = task.euid or task.uid kernel.process = task.name @@ -366,9 +390,29 @@ function kernel.main() task.sleep = 0 end + if task.status == "DS" and kernel.EFI:getEpochMs() >= task.sleep then + task.status = "D" + task.sleep = 0 + end + if task.status == "D" then if task.ksh then coroutine.resume(task.ksh) + if coroutine.status(task.ksh) == "dead" then + task.ksh = nil + if task.status == "D" then + task.status = "R" + end + + if kernel.config.debugSyscalls then + kernel.log("Task " .. task.pid .. " IO wait completed", "DBUG", 0x00FFFF) + local sysret = task.syscallReturn + for i = 2, #sysret do + local v = type(sysret[i]) == "table" and table.serialize(sysret[i]) or tostring(sysret[i]) + kernel.log(" retval[" .. (i-1) .. "] = " .. v, "DBUG", 0x00FFFF) + end + end + end end end @@ -405,7 +449,9 @@ function kernel.main() if task.status == "R" then local startTime = kernel.EFI:getEpochMs() local ret - + if stopLog > 0 then + kernel.log("Running task " .. tostring(task.pid) .. " (" .. task.name .. ") with time slice " .. string.format("%.3f", task.timeSlice) .. "s", "DBUG", 0x00FFFF) + end if kernel.config.preempt then if not task.debugger then ret = { resumeWithTimeout(task.coro, task.timeSlice, table.unpack(task.syscallReturn)) } @@ -491,6 +537,11 @@ function kernel.main() end reapDeadTasks() + if stopLog > 0 then + kernel.log("Executed " .. N .. " tasks, avg time: " .. string.format("%.2f", T_prev_avg) .. "ms, var: " .. string.format("%.2f", T_prev_var) .. ", B: " .. string.format("%.5f", B)) + stopLog = stopLog - 1 + kernel.saveLog() + end end end diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/90_kgc.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/90_kgc.kmod new file mode 100644 index 0000000..9a14d1a --- /dev/null +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/90_kgc.kmod @@ -0,0 +1,11 @@ +local kernel = ... +kernel.processes.kgc = function() + while true do + for i,v in pairs(kernel.reqcache) do + if v.expires and kernel.EFI:getEpochMs() > v.expires then + kernel.reqcache[i] = nil + end + end + kernel.sleep(5000) + end +end \ No newline at end of file diff --git a/Src/hysh/data/bin/login b/Src/coreutils/data/bin/login similarity index 98% rename from Src/hysh/data/bin/login rename to Src/coreutils/data/bin/login index 13659d7..51b9c86 100644 --- a/Src/hysh/data/bin/login +++ b/Src/coreutils/data/bin/login @@ -1,5 +1,5 @@ --:Minify:-- -syscall.open("/dev/tty/1", "r") --stdin (fd 0) +syscall.open("/dev/input/keyboard1", "r") --stdin (fd 0) syscall.open("/dev/tty/1", "w") --stdout (fd 1) syscall.open("/dev/null", "w") --stderr (fd 2) diff --git a/Src/hysh/data/bin/lsusers b/Src/coreutils/data/bin/lsusers similarity index 100% rename from Src/hysh/data/bin/lsusers rename to Src/coreutils/data/bin/lsusers diff --git a/Src/hysh/data/bin/mount b/Src/coreutils/data/bin/mount similarity index 100% rename from Src/hysh/data/bin/mount rename to Src/coreutils/data/bin/mount diff --git a/Src/hysh/data/bin/passwd b/Src/coreutils/data/bin/passwd similarity index 100% rename from Src/hysh/data/bin/passwd rename to Src/coreutils/data/bin/passwd diff --git a/Src/hysh/data/bin/su b/Src/coreutils/data/bin/su similarity index 100% rename from Src/hysh/data/bin/su rename to Src/coreutils/data/bin/su diff --git a/Src/hysh/data/bin/sudo b/Src/coreutils/data/bin/sudo similarity index 100% rename from Src/hysh/data/bin/sudo rename to Src/coreutils/data/bin/sudo diff --git a/Src/hysh/data/bin/umount b/Src/coreutils/data/bin/umount similarity index 100% rename from Src/hysh/data/bin/umount rename to Src/coreutils/data/bin/umount diff --git a/Src/hysh/data/bin/useradd b/Src/coreutils/data/bin/useradd similarity index 100% rename from Src/hysh/data/bin/useradd rename to Src/coreutils/data/bin/useradd diff --git a/Src/hysh/data/bin/userdel b/Src/coreutils/data/bin/userdel similarity index 100% rename from Src/hysh/data/bin/userdel rename to Src/coreutils/data/bin/userdel diff --git a/Src/hysh/data/bin/usermod b/Src/coreutils/data/bin/usermod similarity index 100% rename from Src/hysh/data/bin/usermod rename to Src/coreutils/data/bin/usermod diff --git a/Src/hysh/control/symlinks.json b/Src/hysh/control/symlinks.json new file mode 100644 index 0000000..4a4d945 --- /dev/null +++ b/Src/hysh/control/symlinks.json @@ -0,0 +1,3 @@ +{ + "/bin/sh": "/bin/hysh" +} \ No newline at end of file diff --git a/Src/hysh/data/bin/help b/Src/hysh/data/bin/help index f8938aa..03f40a6 100644 --- a/Src/hysh/data/bin/help +++ b/Src/hysh/data/bin/help @@ -107,6 +107,7 @@ local COMMANDS = { { name="whoami", usage="whoami", desc="Print the current username.", flags={} }, { name="id", usage="id [username]", desc="Print user identity (uid, gid).", flags={} }, { name="ps", usage="ps", desc="List running tasks with pid, user, name, and status.", flags={} }, + { name="hyperctl", usage="hyperctl [service]", desc="Control system services (start, stop, restart, status, list, enable, disable).", flags={} }, { name="hostname", usage="hostname [NAME]", desc="Print or set the system hostname.", flags={} }, { name="uname", usage="uname [-asnrm]", desc="Print system information (OS name, hostname, release, machine).", flags={ {"-a","Print all fields"}, diff --git a/Src/hysh/data/bin/hysh b/Src/hysh/data/bin/hysh index 6bf3655..e18c487 100644 --- a/Src/hysh/data/bin/hysh +++ b/Src/hysh/data/bin/hysh @@ -1,10 +1,10 @@ --:Minify:-- -syscall.open("/dev/tty/1","r") --stdin (Device 0) +local success, errorMsg = xpcall(function() + +syscall.open("/dev/input/keyboard1","r") --stdin (Device 0) syscall.open("/dev/tty/1","w") --stdout (Device 1) syscall.open("/dev/null","w") --stderr (device 2) -local success, errorMsg = xpcall(function() - local fs = require("fs") syscall.devctl(1,"clear") @@ -833,6 +833,14 @@ builtinCmds.ops = function() end end +builtinCmds.reboot = function () + syscall.reboot() +end + +builtinCmds.shutdown = function () + syscall.shutdown() +end + local function listDir(dir, prefix) local ok, entries = pcall(syscall.listdir, dir) if not ok or not entries then return {} end @@ -1203,9 +1211,9 @@ local function runCommand(command) local proc = syscall.spawn(function() -- Open standard fds so programs that don't do it themselves work correctly. - syscall.open("/dev/tty/1", "r") -- fd 0 stdin + syscall.open("/dev/input/keyboard1", "r") -- fd 0 stdin syscall.open("/dev/tty/1", "w") -- fd 1 stdout - syscall.open("/dev/null", "w") -- fd 2 stderr + syscall.open("/dev/null", "w") -- fd 2 stderr -- exec replaces this coroutine's code with a fresh isolated environment -- compiled from disk by the kernel (via loadExecutable -> freshUserEnv), -- so the child cannot share any upvalue or syscall table state with hysh. diff --git a/Src/hysh/data/bin/tree b/Src/hysh/data/bin/tree new file mode 100644 index 0000000..b681c90 --- /dev/null +++ b/Src/hysh/data/bin/tree @@ -0,0 +1,113 @@ +--:Minify:-- +local cloptions = { + a = false, + h = false, + l = false, + help = false, +} +local inpArgs = { ... } +local args = {} +local name = syscall.getTask(syscall.getpid()).name + +for _, v in pairs(inpArgs) do + if v:sub(1, 2) == "--" then + local opt = v:sub(3) + if cloptions[opt] == nil then + print(name .. ": unrecognized option '" .. v .. "'.") + print("try '" .. name .. " --help' for more information.") + return + end + cloptions[opt] = true + elseif v:sub(1, 1) == "-" then + for i = 2, #v do + local opt = v:sub(i, i) + if cloptions[opt] == nil then + print(name .. ": invalid option '-" .. opt .. "'.") + print("try '" .. name .. " --help' for more information.") + return + end + cloptions[opt] = true + end + else + table.insert(args, v) + end +end + +if cloptions.help then + print("Usage: " .. name .. " [OPTION]... [DIR]") + print("List all entries in the specified DIRectory, or cwd if not specified.") + print("Display directory tree structure.") + print("") + print("Options:") + print(" -a do not ignore entries starting with .") + print(" -h with -l, print sizes in human readable format (e.g., 1K 234M 2G)") + print(" -l use a long listing format (show file sizes)") + print(" --help display this help and exit") + return +end + +local fs = require("fs") +local dir = args[1] or "" +if dir:sub(1, 1) ~= "/" then + dir = syscall.getcwd() .. "/" .. dir +end +if dir:sub(-1) ~= "/" then dir = dir .. "/" end + +if not fs.isDir(dir) then + print(name .. ": cannot access '" .. (args[1] or dir) .. "': no such directory") + return +end + +local function format_size(size) + if not cloptions.h then return tostring(size) end + if size < 1024 then return tostring(size) .. "B" + elseif size < 1024*1024 then return string.format("%.1fK", size/1024) + elseif size < 1024*1024*1024 then return string.format("%.1fM", size/1024/1024) + else return string.format("%.1fG", size/1024/1024/1024) end +end + +local function pdir(current_dir, level, prefix) + prefix = prefix or "" + local list = fs.list(current_dir) + if not cloptions.a then + for i = #list, 1, -1 do + if list[i]:sub(1, 1) == "." then table.remove(list, i) end + end + end + table.sort(list) + if current_dir:sub(-1) ~= "/" then current_dir = current_dir .. "/" end + + for i, entry in ipairs(list) do + local full_path = current_dir .. entry + local is_last = (i == #list) + local branch = is_last and "`--" or "|--" + local indent = prefix .. branch + local suffix = "" + local info = "" + + if fs.isDir(full_path) then + suffix = "/" + end + + if cloptions.l then + local stat = fs.stat and fs.stat(full_path) + if stat then + local size = stat.size or 0 + info = " " .. format_size(size) + end + end + + print(indent .. entry .. suffix .. info) + + if fs.isDir(full_path) then + local new_prefix = prefix .. (is_last and " " or "| ") + pcall(pdir, full_path, level + 1, new_prefix) + end + end +end + +-- Print root directory +local root_name = dir:sub(1, -2) -- remove trailing / +if root_name == "" then root_name = "/" end +print(root_name) +pdir(dir, 0, "") \ No newline at end of file diff --git a/Src/installer/data/bin/hyperion-build b/Src/installer/data/bin/hyperion-build new file mode 100644 index 0000000..e69de29 diff --git a/Src/installer/data/bin/install b/Src/installer/data/bin/install new file mode 100644 index 0000000..e69de29 diff --git a/Src/minify/data/bin/minify b/Src/minify/data/bin/minify new file mode 100644 index 0000000..d77a484 --- /dev/null +++ b/Src/minify/data/bin/minify @@ -0,0 +1,29 @@ + +local function usageError() + print( + "\nusage: minify or unminify \n" .. + " The modified code will be printed to the stdout, pipe it to a file,\n" .. + " or something else as desired EG:\n\n" .. + " minify minify input.lua > output.lua\n\n" .. + " * minify will minify the code in the file.\n" .. + " * unminify will beautify the code and replace the variable names with easily\n" .. + " find-replacable ones to aide in reverse engineering minified code.\n") + syscall.exit(0) +end + +local args = {...} + +if #args ~= 2 then + usageError() +end + +local minify = require("minify") +local fs = require("fs") + +if args[1] == 'minify' then + print(minify.minify(fs.readAllText(args[2]))) +elseif args[1] == 'unminify' then + print(minify.beautify(fs.readAllText(args[2]))) +else + usageError() +end diff --git a/Src/minify/data/lib/minify.lua b/Src/minify/data/lib/minify.lua new file mode 100644 index 0000000..1b7d0c6 --- /dev/null +++ b/Src/minify/data/lib/minify.lua @@ -0,0 +1,3106 @@ +--[[ +MIT License + +Copyright (c) 2017 Mark Langen + +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. +]] + +local lib = {} + +local function lookupify(tb) + for _, v in pairs(tb) do + tb[v] = true + end + return tb +end + +local function CountTable(tb) + local c = 0 + for _ in pairs(tb) do c = c + 1 end + return c +end + +local function FormatTableInt(tb, atIndent, ignoreFunc) + if tb.Print then + return tb.Print() + end + atIndent = atIndent or 0 + local useNewlines = (CountTable(tb) > 1) + local baseIndent = string.rep(' ', atIndent + 1) + local out = "{" .. (useNewlines and '\n' or '') + for k, v in pairs(tb) do + if type(v) ~= 'function' and not ignoreFunc(k) then + out = out .. (useNewlines and baseIndent or '') + if type(k) == 'number' then + --nothing to do + elseif type(k) == 'string' and k:match("^[A-Za-z_][A-Za-z0-9_]*$") then + out = out .. k .. " = " + elseif type(k) == 'string' then + out = out .. "[\"" .. k .. "\"] = " + else + out = out .. "[" .. tostring(k) .. "] = " + end + if type(v) == 'string' then + out = out .. "\"" .. v .. "\"" + elseif type(v) == 'number' then + out = out .. v + elseif type(v) == 'table' then + out = out .. FormatTableInt(v, atIndent + (useNewlines and 1 or 0), ignoreFunc) + else + out = out .. tostring(v) + end + if next(tb, k) then + out = out .. "," + end + if useNewlines then + out = out .. '\n' + end + end + end + out = out .. (useNewlines and string.rep(' ', atIndent) or '') .. "}" + return out +end + +local function FormatTable(tb, ignoreFunc) + ignoreFunc = ignoreFunc or function() + return false + end + return FormatTableInt(tb, 0, ignoreFunc) +end + +local WhiteChars = lookupify { ' ', '\n', '\t', '\r' } + +local EscapeForCharacter = { ['\r'] = '\\r', ['\n'] = '\\n', ['\t'] = '\\t', ['"'] = '\\"', ["'"] = "\\'", ['\\'] = '\\' } + +local CharacterForEscape = { ['r'] = '\r', ['n'] = '\n', ['t'] = '\t', ['"'] = '"', ["'"] = "'", ['\\'] = '\\' } + +local AllIdentStartChars = lookupify { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', + 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', + 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', + 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', + 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_' } + +local AllIdentChars = lookupify { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', + 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', + 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', + 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', + 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } + +local Digits = lookupify { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' } + +local HexDigits = lookupify { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f' } + +local Symbols = lookupify { '+', '-', '*', '/', '^', '%', ',', '{', '}', '[', ']', '(', ')', ';', '#', '.', ':' } + +local EqualSymbols = lookupify { '~', '=', '>', '<' } + +local Keywords = lookupify { + 'and', 'break', 'do', 'else', 'elseif', + 'end', 'false', 'for', 'function', 'goto', 'if', + 'in', 'local', 'nil', 'not', 'or', 'repeat', + 'return', 'then', 'true', 'until', 'while', +}; + +local BlockFollowKeyword = lookupify { 'else', 'elseif', 'until', 'end' } + +local UnopSet = lookupify { '-', 'not', '#' } + +local BinopSet = lookupify { + '+', '-', '*', '/', '%', '^', '#', + '..', '.', ':', + '>', '<', '<=', '>=', '~=', '==', + 'and', 'or' +} + +local GlobalRenameIgnore = lookupify { + +} + +local BinaryPriority = { + ['+'] = { 6, 6 }, + ['-'] = { 6, 6 }, + ['*'] = { 7, 7 }, + ['/'] = { 7, 7 }, + ['%'] = { 7, 7 }, + ['^'] = { 10, 9 }, + ['..'] = { 5, 4 }, + ['=='] = { 3, 3 }, + ['~='] = { 3, 3 }, + ['>'] = { 3, 3 }, + ['<'] = { 3, 3 }, + ['>='] = { 3, 3 }, + ['<='] = { 3, 3 }, + ['and'] = { 2, 2 }, + ['or'] = { 1, 1 }, +}; +local UnaryPriority = 8 + +-- Eof, Ident, Keyword, Number, String, Symbol + +local function CreateLuaTokenStream(text) + -- Tracking for the current position in the buffer, and + -- the current line / character we are on. + local p = 1 + local length = #text + + -- Output buffer for tokens + local tokenBuffer = {} + + -- Get a character, or '' if at eof + local function look(n) + n = p + (n or 0) + if n <= length then + return text:sub(n, n) + else + return '' + end + end + local function get() + if p <= length then + local c = text:sub(p, p) + p = p + 1 + return c + else + return '' + end + end + + -- Error + local olderr = error + local function error(str) + local q = 1 + local line = 1 + local char = 1 + while q <= p do + if text:sub(q, q) == '\n' then + line = line + 1 + char = 1 + else + char = char + 1 + end + q = q + 1 + end + for _, token in pairs(tokenBuffer) do + print(token.Type .. "<" .. token.Source .. ">") + end + olderr("file<" .. line .. ":" .. char .. ">: " .. str) + end + + -- Consume a long data with equals count of `eqcount' + local function longdata(eqcount) + while true do + local c = get() + if c == '' then + error("Unfinished long string.") + elseif c == ']' then + local done = true -- Until contested + for i = 1, eqcount do + if look() == '=' then + p = p + 1 + else + done = false + break + end + end + if done and get() == ']' then + return + end + end + end + end + + -- Get the opening part for a long data `[` `=`* `[` + -- Precondition: The first `[` has been consumed + -- Return: nil or the equals count + local function getopen() + local startp = p + while look() == '=' do + p = p + 1 + end + if look() == '[' then + p = p + 1 + return p - startp - 1 + else + p = startp + return nil + end + end + + -- Add token + local whiteStart = 1 + local tokenStart = 1 + local function token(type) + local tk = { + Type = type, + LeadingWhite = text:sub(whiteStart, tokenStart - 1), + Source = text:sub(tokenStart, p - 1), + } + table.insert(tokenBuffer, tk) + whiteStart = p + tokenStart = p + return tk + end + + -- Parse tokens loop + while true do + -- Mark the whitespace start + whiteStart = p + + -- Get the leading whitespace + comments + while true do + local c = look() + if c == '' then + break + elseif c == '-' then + if look(1) == '-' then + p = p + 2 + -- Consume comment body + if look() == '[' then + p = p + 1 + local eqcount = getopen() + if eqcount then + -- Long comment body + longdata(eqcount) + else + -- Normal comment body + while true do + local c2 = get() + if c2 == '' or c2 == '\n' then + break + end + end + end + else + -- Normal comment body + while true do + local c2 = get() + if c2 == '' or c2 == '\n' then + break + end + end + end + else + break + end + elseif WhiteChars[c] then + p = p + 1 + else + break + end + end + local leadingWhite = text:sub(whiteStart, p - 1) + + -- Mark the token start + tokenStart = p + + -- Switch on token type + local c1 = get() + if c1 == '' then + -- End of file + token('Eof') + break + elseif c1 == '\'' or c1 == '\"' then + -- String constant + while true do + local c2 = get() + if c2 == '\\' then + local c3 = get() + local esc = CharacterForEscape[c3] + if not esc then + error("Invalid Escape Sequence `" .. c3 .. "`.") + end + elseif c2 == c1 then + break + end + end + token('String') + elseif AllIdentStartChars[c1] then + -- Ident or Keyword + while AllIdentChars[look()] do + p = p + 1 + end + if Keywords[text:sub(tokenStart, p - 1)] then + token('Keyword') + else + token('Ident') + end + elseif Digits[c1] or (c1 == '.' and Digits[look()]) then + -- Number + if c1 == '0' and look() == 'x' then + p = p + 1 + -- Hex number + while HexDigits[look()] do + p = p + 1 + end + else + -- Normal Number + while Digits[look()] do + p = p + 1 + end + if look() == '.' then + -- With decimal point + p = p + 1 + while Digits[look()] do + p = p + 1 + end + end + if look() == 'e' or look() == 'E' then + -- With exponent + p = p + 1 + if look() == '-' then + p = p + 1 + end + while Digits[look()] do + p = p + 1 + end + end + end + token('Number') + elseif c1 == '[' then + -- '[' Symbol or Long String + local eqCount = getopen() + if eqCount then + -- Long string + longdata(eqCount) + token('String') + else + -- Symbol + token('Symbol') + end + elseif c1 == '.' then + -- Greedily consume up to 3 `.` for . / .. / ... tokens + if look() == '.' then + get() + if look() == '.' then + get() + end + end + token('Symbol') + elseif EqualSymbols[c1] then + if look() == '=' then + p = p + 1 + end + token('Symbol') + elseif c1 == ':' then + -- ':' or '::' + if look() == ':' then + get() + end + token('Symbol') + elseif Symbols[c1] then + token('Symbol') + else + error("Bad symbol `" .. c1 .. "` in source.") + end + end + return tokenBuffer +end + +local function CreateLuaParser(text) + -- Token stream and pointer into it + local tokens = CreateLuaTokenStream(text) + -- for _, tok in pairs(tokens) do + -- print(tok.Type..": "..tok.Source) + -- end + local p = 1 + + local function get() + local tok = tokens[p] + if p < #tokens then + p = p + 1 + end + return tok + end + local function peek(n) + n = p + (n or 0) + return tokens[n] or tokens[#tokens] + end + + local function getTokenStartPosition(token) + local line = 1 + local char = 0 + local tkNum = 1 + while true do + local tk = tokens[tkNum] + local text; + if tk == token then + text = tk.LeadingWhite + else + text = tk.LeadingWhite .. tk.Source + end + for i = 1, #text do + local c = text:sub(i, i) + if c == '\n' then + line = line + 1 + char = 0 + else + char = char + 1 + end + end + if tk == token then + break + end + tkNum = tkNum + 1 + end + return line .. ":" .. (char + 1) + end + local function debugMark() + local tk = peek() + return "<" .. tk.Type .. " `" .. tk.Source .. "`> at: " .. getTokenStartPosition(tk) + end + + local function isBlockFollow() + local tok = peek() + return tok.Type == 'Eof' or (tok.Type == 'Keyword' and BlockFollowKeyword[tok.Source]) + end + local function isUnop() + return UnopSet[peek().Source] or false + end + local function isBinop() + return BinopSet[peek().Source] or false + end + local function expect(type, source) + local tk = peek() + if tk.Type == type and (source == nil or tk.Source == source) then + return get() + else + for i = -3, 3 do + print("Tokens[" .. i .. "] = `" .. peek(i).Source .. "`") + end + if source then + error(getTokenStartPosition(tk) .. ": `" .. source .. "` expected.") + else + error(getTokenStartPosition(tk) .. ": " .. type .. " expected.") + end + end + end + + local function MkNode(node) + local getf = node.GetFirstToken + local getl = node.GetLastToken + function node:GetFirstToken() + local t = getf(self) + assert(t) + return t + end + + function node:GetLastToken() + local t = getl(self) + assert(t) + return t + end + + return node + end + + -- Forward decls + local block; + local expr; + + -- Expression list + local function exprlist() + local exprList = {} + local commaList = {} + table.insert(exprList, expr()) + while peek().Source == ',' do + table.insert(commaList, get()) + table.insert(exprList, expr()) + end + return exprList, commaList + end + + local function prefixexpr() + local tk = peek() + if tk.Source == '(' then + local oparenTk = get() + local inner = expr() + local cparenTk = expect('Symbol', ')') + return MkNode { + Type = 'ParenExpr', + Expression = inner, + Token_OpenParen = oparenTk, + Token_CloseParen = cparenTk, + GetFirstToken = function(self) + return self.Token_OpenParen + end, + GetLastToken = function(self) + return self.Token_CloseParen + end, + } + elseif tk.Type == 'Ident' then + return MkNode { + Type = 'VariableExpr', + Token = get(), + GetFirstToken = function(self) + return self.Token + end, + GetLastToken = function(self) + return self.Token + end, + } + else + print(debugMark()) + error(getTokenStartPosition(tk) .. ": Unexpected symbol") + end + end + + local function tableexpr() + local obrace = expect('Symbol', '{') + local entries = {} + local separators = {} + while peek().Source ~= '}' do + if peek().Source == '[' then + -- Index + local obrac = get() + local index = expr() + local cbrac = expect('Symbol', ']') + local eq = expect('Symbol', '=') + local value = expr() + table.insert(entries, { + EntryType = 'Index', + Index = index, + Value = value, + Token_OpenBracket = obrac, + Token_CloseBracket = cbrac, + Token_Equals = eq, + }) + elseif peek().Type == 'Ident' and peek(1).Source == '=' then + -- Field + local field = get() + local eq = get() + local value = expr() + table.insert(entries, { + EntryType = 'Field', + Field = field, + Value = value, + Token_Equals = eq, + }) + else + -- Value + local value = expr() + table.insert(entries, { + EntryType = 'Value', + Value = value, + }) + end + + -- Comma or Semicolon separator + if peek().Source == ',' or peek().Source == ';' then + table.insert(separators, get()) + else + break + end + end + local cbrace = expect('Symbol', '}') + return MkNode { + Type = 'TableLiteral', + EntryList = entries, + Token_SeparatorList = separators, + Token_OpenBrace = obrace, + Token_CloseBrace = cbrace, + GetFirstToken = function(self) + return self.Token_OpenBrace + end, + GetLastToken = function(self) + return self.Token_CloseBrace + end, + } + end + + -- List of identifiers + local function varlist() + local varList = {} + local commaList = {} + local hasVararg = false + + -- first item + if peek().Source == '...' then + table.insert(varList, get()) + hasVararg = true + elseif peek().Type == 'Ident' then + table.insert(varList, get()) + end + + -- remaining items + while peek().Source == ',' do + table.insert(commaList, get()) + + if peek().Source == '...' then + table.insert(varList, get()) + hasVararg = true + break -- vararg must be last + else + table.insert(varList, expect('Ident')) + end + end + + return varList, commaList, hasVararg + end + + -- Body + local function blockbody(terminator) + local body = block() + local after = peek() + if after.Type == 'Keyword' and after.Source == terminator then + get() + return body, after + else + print(after.Type, after.Source) + error(getTokenStartPosition(after) .. ": " .. terminator .. " expected.") + end + end + + -- Function declaration + local function funcdecl(isAnonymous) + local functionKw = get() + -- + local nameChain; + local nameChainSeparator; + -- + if not isAnonymous then + nameChain = {} + nameChainSeparator = {} + -- + table.insert(nameChain, expect('Ident')) + -- + while peek().Source == '.' do + table.insert(nameChainSeparator, get()) + table.insert(nameChain, expect('Ident')) + end + if peek().Source == ':' then + table.insert(nameChainSeparator, get()) + table.insert(nameChain, expect('Ident')) + end + end + -- + local oparenTk = expect('Symbol', '(') + local argList, argCommaList, hasVararg = varlist() + local cparenTk = expect('Symbol', ')') + local fbody, enTk = blockbody('end') + -- + return MkNode { + Type = (isAnonymous and 'FunctionLiteral' or 'FunctionStat'), + NameChain = nameChain, + ArgList = argList, + Body = fbody, + HasVararg = hasVararg, + -- + Token_Function = functionKw, + Token_NameChainSeparator = nameChainSeparator, + Token_OpenParen = oparenTk, + Token_ArgCommaList = argCommaList, + Token_CloseParen = cparenTk, + Token_End = enTk, + GetFirstToken = function(self) + return self.Token_Function + end, + GetLastToken = function(self) + return self.Token_End; + end, + } + end + + -- Argument list passed to a funciton + local function functionargs() + local tk = peek() + if tk.Source == '(' then + local oparenTk = get() + local argList = {} + local argCommaList = {} + while peek().Source ~= ')' do + table.insert(argList, expr()) + if peek().Source == ',' then + table.insert(argCommaList, get()) + else + break + end + end + local cparenTk = expect('Symbol', ')') + return MkNode { + CallType = 'ArgCall', + ArgList = argList, + -- + Token_CommaList = argCommaList, + Token_OpenParen = oparenTk, + Token_CloseParen = cparenTk, + GetFirstToken = function(self) + return self.Token_OpenParen + end, + GetLastToken = function(self) + return self.Token_CloseParen + end, + } + elseif tk.Source == '{' then + return MkNode { + CallType = 'TableCall', + TableExpr = expr(), + GetFirstToken = function(self) + return self.TableExpr:GetFirstToken() + end, + GetLastToken = function(self) + return self.TableExpr:GetLastToken() + end, + } + elseif tk.Type == 'String' then + return MkNode { + CallType = 'StringCall', + Token = get(), + GetFirstToken = function(self) + return self.Token + end, + GetLastToken = function(self) + return self.Token + end, + } + else + error("Function arguments expected.") + end + end + + local function primaryexpr() + local base = prefixexpr() + assert(base, "nil prefixexpr") + while true do + local tk = peek() + if tk.Source == '.' then + local dotTk = get() + local fieldName = expect('Ident') + base = MkNode { + Type = 'FieldExpr', + Base = base, + Field = fieldName, + Token_Dot = dotTk, + GetFirstToken = function(self) + return self.Base:GetFirstToken() + end, + GetLastToken = function(self) + return self.Field + end, + } + elseif tk.Source == ':' then + local colonTk = get() + local methodName = expect('Ident') + local fargs = functionargs() + base = MkNode { + Type = 'MethodExpr', + Base = base, + Method = methodName, + FunctionArguments = fargs, + Token_Colon = colonTk, + GetFirstToken = function(self) + return self.Base:GetFirstToken() + end, + GetLastToken = function(self) + return self.FunctionArguments:GetLastToken() + end, + } + elseif tk.Source == '[' then + local obrac = get() + local index = expr() + local cbrac = expect('Symbol', ']') + base = MkNode { + Type = 'IndexExpr', + Base = base, + Index = index, + Token_OpenBracket = obrac, + Token_CloseBracket = cbrac, + GetFirstToken = function(self) + return self.Base:GetFirstToken() + end, + GetLastToken = function(self) + return self.Token_CloseBracket + end, + } + elseif tk.Source == '{' then + base = MkNode { + Type = 'CallExpr', + Base = base, + FunctionArguments = functionargs(), + GetFirstToken = function(self) + return self.Base:GetFirstToken() + end, + GetLastToken = function(self) + return self.FunctionArguments:GetLastToken() + end, + } + elseif tk.Source == '(' then + base = MkNode { + Type = 'CallExpr', + Base = base, + FunctionArguments = functionargs(), + GetFirstToken = function(self) + return self.Base:GetFirstToken() + end, + GetLastToken = function(self) + return self.FunctionArguments:GetLastToken() + end, + } + else + return base + end + end + end + + local function simpleexpr() + local tk = peek() + if tk.Type == 'Number' then + return MkNode { + Type = 'NumberLiteral', + Token = get(), + GetFirstToken = function(self) + return self.Token + end, + GetLastToken = function(self) + return self.Token + end, + } + elseif tk.Type == 'String' then + return MkNode { + Type = 'StringLiteral', + Token = get(), + GetFirstToken = function(self) + return self.Token + end, + GetLastToken = function(self) + return self.Token + end, + } + elseif tk.Source == 'nil' then + return MkNode { + Type = 'NilLiteral', + Token = get(), + GetFirstToken = function(self) + return self.Token + end, + GetLastToken = function(self) + return self.Token + end, + } + elseif tk.Source == 'true' or tk.Source == 'false' then + return MkNode { + Type = 'BooleanLiteral', + Token = get(), + GetFirstToken = function(self) + return self.Token + end, + GetLastToken = function(self) + return self.Token + end, + } + elseif tk.Source == '...' then + return MkNode { + Type = 'VargLiteral', + Token = get(), + GetFirstToken = function(self) + return self.Token + end, + GetLastToken = function(self) + return self.Token + end, + } + elseif tk.Source == '{' then + return tableexpr() + elseif tk.Source == 'function' then + return funcdecl(true) + else + return primaryexpr() + end + end + + local function subexpr(limit) + local curNode; + + -- Initial Base Expression + if isUnop() then + local opTk = get() + local ex = subexpr(UnaryPriority) + curNode = MkNode { + Type = 'UnopExpr', + Token_Op = opTk, + Rhs = ex, + GetFirstToken = function(self) + return self.Token_Op + end, + GetLastToken = function(self) + return self.Rhs:GetLastToken() + end, + } + else + curNode = simpleexpr() + assert(curNode, "nil simpleexpr") + end + + -- Apply Precedence Recursion Chain + while isBinop() and BinaryPriority[peek().Source][1] > limit do + local opTk = get() + local rhs = subexpr(BinaryPriority[opTk.Source][2]) + assert(rhs, "RhsNeeded") + curNode = MkNode { + Type = 'BinopExpr', + Lhs = curNode, + Rhs = rhs, + Token_Op = opTk, + GetFirstToken = function(self) + return self.Lhs:GetFirstToken() + end, + GetLastToken = function(self) + return self.Rhs:GetLastToken() + end, + } + end + + -- Return result + return curNode + end + + -- Expression + expr = function() + return subexpr(0) + end + + -- Expression statement + local function exprstat() + local ex = primaryexpr() + if ex.Type == 'MethodExpr' or ex.Type == 'CallExpr' then + -- all good, calls can be statements + return MkNode { + Type = 'CallExprStat', + Expression = ex, + GetFirstToken = function(self) + return self.Expression:GetFirstToken() + end, + GetLastToken = function(self) + return self.Expression:GetLastToken() + end, + } + else + -- Assignment expr + local lhs = { ex } + local lhsSeparator = {} + while peek().Source == ',' do + table.insert(lhsSeparator, get()) + local lhsPart = primaryexpr() + if lhsPart.Type == 'MethodExpr' or lhsPart.Type == 'CallExpr' then + error("Bad left hand side of assignment") + end + table.insert(lhs, lhsPart) + end + local eq = expect('Symbol', '=') + local rhs = { expr() } + local rhsSeparator = {} + while peek().Source == ',' do + table.insert(rhsSeparator, get()) + table.insert(rhs, expr()) + end + return MkNode { + Type = 'AssignmentStat', + Rhs = rhs, + Lhs = lhs, + Token_Equals = eq, + Token_LhsSeparatorList = lhsSeparator, + Token_RhsSeparatorList = rhsSeparator, + GetFirstToken = function(self) + return self.Lhs[1]:GetFirstToken() + end, + GetLastToken = function(self) + return self.Rhs[#self.Rhs]:GetLastToken() + end, + } + end + end + + -- If statement + local function ifstat() + local ifKw = get() + local condition = expr() + local thenKw = expect('Keyword', 'then') + local ifBody = block() + local elseClauses = {} + while peek().Source == 'elseif' or peek().Source == 'else' do + local elseifKw = get() + local elseifCondition, elseifThenKw; + if elseifKw.Source == 'elseif' then + elseifCondition = expr() + elseifThenKw = expect('Keyword', 'then') + end + local elseifBody = block() + table.insert(elseClauses, { + Condition = elseifCondition, + Body = elseifBody, + -- + ClauseType = elseifKw.Source, + Token = elseifKw, + Token_Then = elseifThenKw, + }) + if elseifKw.Source == 'else' then + break + end + end + local enKw = expect('Keyword', 'end') + return MkNode { + Type = 'IfStat', + Condition = condition, + Body = ifBody, + ElseClauseList = elseClauses, + -- + Token_If = ifKw, + Token_Then = thenKw, + Token_End = enKw, + GetFirstToken = function(self) + return self.Token_If + end, + GetLastToken = function(self) + return self.Token_End + end, + } + end + + -- Do statement + local function dostat() + local doKw = get() + local body, enKw = blockbody('end') + -- + return MkNode { + Type = 'DoStat', + Body = body, + -- + Token_Do = doKw, + Token_End = enKw, + GetFirstToken = function(self) + return self.Token_Do + end, + GetLastToken = function(self) + return self.Token_End + end, + } + end + + -- While statement + local function whilestat() + local whileKw = get() + local condition = expr() + local doKw = expect('Keyword', 'do') + local body, enKw = blockbody('end') + -- + return MkNode { + Type = 'WhileStat', + Condition = condition, + Body = body, + -- + Token_While = whileKw, + Token_Do = doKw, + Token_End = enKw, + GetFirstToken = function(self) + return self.Token_While + end, + GetLastToken = function(self) + return self.Token_End + end, + } + end + + -- For statement + local function forstat() + local forKw = get() + local loopVars, loopVarCommas = varlist() + local node = {} + if peek().Source == '=' then + local eqTk = get() + local exprList, exprCommaList = exprlist() + if #exprList < 2 or #exprList > 3 then + error("expected 2 or 3 values for range bounds") + end + local doTk = expect('Keyword', 'do') + local body, enTk = blockbody('end') + return MkNode { + Type = 'NumericForStat', + VarList = loopVars, + RangeList = exprList, + Body = body, + -- + Token_For = forKw, + Token_VarCommaList = loopVarCommas, + Token_Equals = eqTk, + Token_RangeCommaList = exprCommaList, + Token_Do = doTk, + Token_End = enTk, + GetFirstToken = function(self) + return self.Token_For + end, + GetLastToken = function(self) + return self.Token_End + end, + } + elseif peek().Source == 'in' then + local inTk = get() + local exprList, exprCommaList = exprlist() + local doTk = expect('Keyword', 'do') + local body, enTk = blockbody('end') + return MkNode { + Type = 'GenericForStat', + VarList = loopVars, + GeneratorList = exprList, + Body = body, + -- + Token_For = forKw, + Token_VarCommaList = loopVarCommas, + Token_In = inTk, + Token_GeneratorCommaList = exprCommaList, + Token_Do = doTk, + Token_End = enTk, + GetFirstToken = function(self) + return self.Token_For + end, + GetLastToken = function(self) + return self.Token_End + end, + } + else + error("`=` or in expected") + end + end + + -- Repeat statement + local function repeatstat() + local repeatKw = get() + local body, untilTk = blockbody('until') + local condition = expr() + return MkNode { + Type = 'RepeatStat', + Body = body, + Condition = condition, + -- + Token_Repeat = repeatKw, + Token_Until = untilTk, + GetFirstToken = function(self) + return self.Token_Repeat + end, + GetLastToken = function(self) + return self.Condition:GetLastToken() + end, + } + end + + -- Local var declaration + local function localdecl() + local localKw = get() + if peek().Source == 'function' then + -- Local function def + local funcStat = funcdecl(false) + if #funcStat.NameChain > 1 then + error(getTokenStartPosition(funcStat.Token_NameChainSeparator[1]) .. ": `(` expected.") + end + return MkNode { + Type = 'LocalFunctionStat', + FunctionStat = funcStat, + Token_Local = localKw, + GetFirstToken = function(self) + return self.Token_Local + end, + GetLastToken = function(self) + return self.FunctionStat:GetLastToken() + end, + } + elseif peek().Type == 'Ident' then + -- Local variable declaration + local varList, varCommaList, hasVararg = varlist() + local exprList, exprCommaList = {}, {} + local eqToken; + if peek().Source == '=' then + eqToken = get() + exprList, exprCommaList = exprlist() + end + return MkNode { + Type = 'LocalVarStat', + VarList = varList, + ExprList = exprList, + HasVararg = hasVararg, + Token_Local = localKw, + Token_Equals = eqToken, + Token_VarCommaList = varCommaList, + Token_ExprCommaList = exprCommaList, + GetFirstToken = function(self) + return self.Token_Local + end, + GetLastToken = function(self) + if #self.ExprList > 0 then + return self.ExprList[#self.ExprList]:GetLastToken() + else + return self.VarList[#self.VarList] + end + end, + } + else + error("`function` or ident expected") + end + end + + -- Return statement + local function retstat() + local returnKw = get() + local exprList; + local commaList; + if isBlockFollow() or peek().Source == ';' then + exprList = {} + commaList = {} + else + exprList, commaList = exprlist() + end + return { + Type = 'ReturnStat', + ExprList = exprList, + Token_Return = returnKw, + Token_CommaList = commaList, + GetFirstToken = function(self) + return self.Token_Return + end, + GetLastToken = function(self) + if #self.ExprList > 0 then + return self.ExprList[#self.ExprList]:GetLastToken() + else + return self.Token_Return + end + end, + } + end + + -- Break statement + local function breakstat() + local breakKw = get() + return { + Type = 'BreakStat', + Token_Break = breakKw, + GetFirstToken = function(self) + return self.Token_Break + end, + GetLastToken = function(self) + return self.Token_Break + end, + } + end + + local function labelstat() + local open1 = expect('Symbol', '::') + local name = expect('Ident') + local open2 = expect('Symbol', '::') + + return MkNode { + Type = 'LabelStat', + Label = name, + + Token_Open1 = open1, + Token_Name = name, + Token_Open2 = open2, + + GetFirstToken = function(self) + return self.Token_Open1 + end, + + GetLastToken = function(self) + return self.Token_Open2 + end, + } + end + + local function gotostat() + local gotoKw = get() + local label = expect('Ident') + + return MkNode { + Type = 'GotoStat', + Label = label, + + Token_Goto = gotoKw, + Token_Label = label, + + GetFirstToken = function(self) + return self.Token_Goto + end, + + GetLastToken = function(self) + return self.Token_Label + end, + } + end + + -- Expression + local function statement() + local tok = peek() + if tok.Source == 'if' then + return false, ifstat() + elseif tok.Source == 'while' then + return false, whilestat() + elseif tok.Source == 'do' then + return false, dostat() + elseif tok.Source == 'for' then + return false, forstat() + elseif tok.Source == 'repeat' then + return false, repeatstat() + elseif tok.Source == 'function' then + return false, funcdecl(false) + elseif tok.Source == 'local' then + return false, localdecl() + elseif tok.Source == 'return' then + return true, retstat() + elseif tok.Source == 'break' then + return true, breakstat() + elseif tok.Source == 'goto' then + return false, gotostat() + elseif tok.Source == '::' then + return false, labelstat() + else + return false, exprstat() + end + end + + -- Chunk + block = function() + local statements = {} + local semicolons = {} + local isLast = false + while not isLast and not isBlockFollow() do + -- Parse statement + local stat; + isLast, stat = statement() + table.insert(statements, stat) + local next = peek() + if next.Type == 'Symbol' and next.Source == ';' then + semicolons[#statements] = get() + end + end + return { + Type = 'StatList', + StatementList = statements, + SemicolonList = semicolons, + GetFirstToken = function(self) + if #self.StatementList == 0 then + return nil + else + return self.StatementList[1]:GetFirstToken() + end + end, + GetLastToken = function(self) + if #self.StatementList == 0 then + return nil + elseif self.SemicolonList[#self.StatementList] then + -- Last token may be one of the semicolon separators + return self.SemicolonList[#self.StatementList] + else + return self.StatementList[#self.StatementList]:GetLastToken() + end + end, + } + end + + return block() +end + +local function VisitAst(ast, visitors) + local ExprType = lookupify { + 'BinopExpr', 'UnopExpr', + 'NumberLiteral', 'StringLiteral', 'NilLiteral', 'BooleanLiteral', 'VargLiteral', + 'FieldExpr', 'IndexExpr', + 'MethodExpr', 'CallExpr', + 'FunctionLiteral', + 'VariableExpr', + 'ParenExpr', + 'TableLiteral', + } + + local StatType = lookupify { + 'StatList', + 'BreakStat', + 'ReturnStat', + 'LocalVarStat', + 'LocalFunctionStat', + 'FunctionStat', + 'RepeatStat', + 'GenericForStat', + 'NumericForStat', + 'WhileStat', + 'DoStat', + 'IfStat', + 'CallExprStat', + 'AssignmentStat', + } + + -- Check for typos in visitor construction + for visitorSubject, visitor in pairs(visitors) do + if not StatType[visitorSubject] and not ExprType[visitorSubject] then + error("Invalid visitor target: `" .. visitorSubject .. "`") + end + end + + -- Helpers to call visitors on a node + local function preVisit(exprOrStat) + local visitor = visitors[exprOrStat.Type] + if type(visitor) == 'function' then + return visitor(exprOrStat) + elseif visitor and visitor.Pre then + return visitor.Pre(exprOrStat) + end + end + local function postVisit(exprOrStat) + local visitor = visitors[exprOrStat.Type] + if visitor and type(visitor) == 'table' and visitor.Post then + return visitor.Post(exprOrStat) + end + end + + local visitExpr, visitStat; + + visitExpr = function(expr) + if preVisit(expr) then + -- Handler did custom child iteration or blocked child iteration + return + end + if expr.Type == 'BinopExpr' then + visitExpr(expr.Lhs) + visitExpr(expr.Rhs) + elseif expr.Type == 'UnopExpr' then + visitExpr(expr.Rhs) + elseif expr.Type == 'NumberLiteral' or expr.Type == 'StringLiteral' or + expr.Type == 'NilLiteral' or expr.Type == 'BooleanLiteral' or + expr.Type == 'VargLiteral' + then + -- No children to visit, single token literals + elseif expr.Type == 'FieldExpr' then + visitExpr(expr.Base) + elseif expr.Type == 'IndexExpr' then + visitExpr(expr.Base) + visitExpr(expr.Index) + elseif expr.Type == 'MethodExpr' or expr.Type == 'CallExpr' then + visitExpr(expr.Base) + if expr.FunctionArguments.CallType == 'ArgCall' then + for index, argExpr in pairs(expr.FunctionArguments.ArgList) do + visitExpr(argExpr) + end + elseif expr.FunctionArguments.CallType == 'TableCall' then + visitExpr(expr.FunctionArguments.TableExpr) + end + elseif expr.Type == 'FunctionLiteral' then + visitStat(expr.Body) + elseif expr.Type == 'VariableExpr' then + -- No children to visit + elseif expr.Type == 'ParenExpr' then + visitExpr(expr.Expression) + elseif expr.Type == 'TableLiteral' then + for index, entry in pairs(expr.EntryList) do + if entry.EntryType == 'Field' then + visitExpr(entry.Value) + elseif entry.EntryType == 'Index' then + visitExpr(entry.Index) + visitExpr(entry.Value) + elseif entry.EntryType == 'Value' then + visitExpr(entry.Value) + else + assert(false, "unreachable") + end + end + else + assert(false, "unreachable, type: " .. expr.Type .. ":" .. FormatTable(expr)) + end + postVisit(expr) + end + + visitStat = function(stat) + if preVisit(stat) then + -- Handler did custom child iteration or blocked child iteration + return + end + if stat.Type == 'StatList' then + for index, ch in pairs(stat.StatementList) do + visitStat(ch) + end + elseif stat.Type == 'BreakStat' then + -- No children to visit + elseif stat.Type == 'ReturnStat' then + for index, expr in pairs(stat.ExprList) do + visitExpr(expr) + end + elseif stat.Type == 'LocalVarStat' then + if stat.Token_Equals then + for index, expr in pairs(stat.ExprList) do + visitExpr(expr) + end + end + elseif stat.Type == 'LocalFunctionStat' then + visitStat(stat.FunctionStat.Body) + elseif stat.Type == 'FunctionStat' then + visitStat(stat.Body) + elseif stat.Type == 'RepeatStat' then + visitStat(stat.Body) + visitExpr(stat.Condition) + elseif stat.Type == 'GenericForStat' then + for index, expr in pairs(stat.GeneratorList) do + visitExpr(expr) + end + visitStat(stat.Body) + elseif stat.Type == 'NumericForStat' then + for index, expr in pairs(stat.RangeList) do + visitExpr(expr) + end + visitStat(stat.Body) + elseif stat.Type == 'WhileStat' then + visitExpr(stat.Condition) + visitStat(stat.Body) + elseif stat.Type == 'DoStat' then + visitStat(stat.Body) + elseif stat.Type == 'IfStat' then + visitExpr(stat.Condition) + visitStat(stat.Body) + for _, clause in pairs(stat.ElseClauseList) do + if clause.Condition then + visitExpr(clause.Condition) + end + visitStat(clause.Body) + end + elseif stat.Type == 'CallExprStat' then + visitExpr(stat.Expression) + elseif stat.Type == 'AssignmentStat' then + for index, ex in pairs(stat.Lhs) do + visitExpr(ex) + end + for index, ex in pairs(stat.Rhs) do + visitExpr(ex) + end + else + assert(false, "unreachable") + end + postVisit(stat) + end + + if StatType[ast.Type] then + visitStat(ast) + else + visitExpr(ast) + end +end + +local function AddVariableInfo(ast) + local globalVars = {} + local currentScope = nil + + -- Numbering generator for variable lifetimes + local locationGenerator = 0 + local function markLocation() + locationGenerator = locationGenerator + 1 + return locationGenerator + end + + -- Scope management + local function pushScope() + currentScope = { + ParentScope = currentScope, + ChildScopeList = {}, + VariableList = {}, + BeginLocation = markLocation(), + } + if currentScope.ParentScope then + currentScope.Depth = currentScope.ParentScope.Depth + 1 + table.insert(currentScope.ParentScope.ChildScopeList, currentScope) + else + currentScope.Depth = 1 + end + function currentScope:GetVar(varName) + for _, var in pairs(self.VariableList) do + if var.Name == varName then + return var + end + end + if self.ParentScope then + return self.ParentScope:GetVar(varName) + else + for _, var in pairs(globalVars) do + if var.Name == varName then + return var + end + end + end + end + end + local function popScope() + local scope = currentScope + + -- Mark where this scope ends + scope.EndLocation = markLocation() + + -- Mark all of the variables in the scope as ending there + for _, var in pairs(scope.VariableList) do + var.ScopeEndLocation = scope.EndLocation + end + + -- Move to the parent scope + currentScope = scope.ParentScope + + return scope + end + pushScope() -- push initial scope + + -- Add / reference variables + local function addLocalVar(name, setNameFunc, localInfo) + assert(localInfo, "Misisng localInfo") + assert(name, "Missing local var name") + local var = { + Type = 'Local', + Name = name, + RenameList = { setNameFunc }, + AssignedTo = false, + Info = localInfo, + UseCount = 0, + Scope = currentScope, + BeginLocation = markLocation(), + EndLocation = markLocation(), + ReferenceLocationList = { markLocation() }, + } + function var:Rename(newName) + self.Name = newName + for _, renameFunc in pairs(self.RenameList) do + renameFunc(newName) + end + end + + function var:Reference() + self.UseCount = self.UseCount + 1 + end + + table.insert(currentScope.VariableList, var) + return var + end + local function getGlobalVar(name) + for _, var in pairs(globalVars) do + if var.Name == name then + return var + end + end + local var = { + Type = 'Global', + Name = name, + RenameList = {}, + AssignedTo = false, + UseCount = 0, + Scope = nil, -- Globals have no scope + BeginLocation = markLocation(), + EndLocation = markLocation(), + ReferenceLocationList = {}, + } + function var:Rename(newName) + self.Name = newName + for _, renameFunc in pairs(self.RenameList) do + renameFunc(newName) + end + end + + function var:Reference() + self.UseCount = self.UseCount + 1 + end + + table.insert(globalVars, var) + return var + end + local function addGlobalReference(name, setNameFunc) + assert(name, "Missing var name") + local var = getGlobalVar(name) + table.insert(var.RenameList, setNameFunc) + return var + end + local function getLocalVar(scope, name) + -- First search this scope + -- Note: Reverse iterate here because Lua does allow shadowing a local + -- within the same scope, and the later defined variable should + -- be the one referenced. + for i = #scope.VariableList, 1, -1 do + if scope.VariableList[i].Name == name then + return scope.VariableList[i] + end + end + + -- Then search parent scope + if scope.ParentScope then + local var = getLocalVar(scope.ParentScope, name) + if var then + return var + end + end + + -- Then + return nil + end + local function referenceVariable(name, setNameFunc) + assert(name, "Missing var name") + local var = getLocalVar(currentScope, name) + if var then + table.insert(var.RenameList, setNameFunc) + else + var = addGlobalReference(name, setNameFunc) + end + -- Update the end location of where this variable is used, and + -- add this location to the list of references to this variable. + local curLocation = markLocation() + var.EndLocation = curLocation + table.insert(var.ReferenceLocationList, var.EndLocation) + return var + end + + local visitor = {} + visitor.FunctionLiteral = { + -- Function literal adds a new scope and adds the function literal arguments + -- as local variables in the scope. + Pre = function(expr) + pushScope() + for index, ident in pairs(expr.ArgList) do + local var = addLocalVar(ident.Source, function(name) + ident.Source = name + end, { + Type = 'Argument', + Index = index, + }) + end + end, + Post = function(expr) + popScope() + end, + } + visitor.VariableExpr = function(expr) + -- Variable expression references from existing local varibales + -- in the current scope, annotating the variable usage with variable + -- information. + expr.Variable = referenceVariable(expr.Token.Source, function(newName) + expr.Token.Source = newName + end) + end + visitor.StatList = { + -- StatList adds a new scope + Pre = function(stat) + pushScope() + end, + Post = function(stat) + popScope() + end, + } + visitor.LocalVarStat = { + Post = function(stat) + -- Local var stat adds the local variables to the current scope as locals + -- We need to visit the subexpressions first, because these new locals + -- will not be in scope for the initialization value expressions. That is: + -- `local bar = bar + 1` + -- Is valid code + for varNum, ident in pairs(stat.VarList) do + addLocalVar(ident.Source, function(name) + stat.VarList[varNum].Source = name + end, { + Type = 'Local', + }) + end + end, + } + visitor.LocalFunctionStat = { + Pre = function(stat) + -- Local function stat adds the function itself to the current scope as + -- a local variable, and creates a new scope with the function arguments + -- as local variables. + addLocalVar(stat.FunctionStat.NameChain[1].Source, function(name) + stat.FunctionStat.NameChain[1].Source = name + end, { + Type = 'LocalFunction', + }) + pushScope() + for index, ident in pairs(stat.FunctionStat.ArgList) do + addLocalVar(ident.Source, function(name) + ident.Source = name + end, { + Type = 'Argument', + Index = index, + }) + end + end, + Post = function() + popScope() + end, + } + visitor.FunctionStat = { + Pre = function(stat) + -- Function stat adds a new scope containing the function arguments + -- as local variables. + -- A function stat may also assign to a global variable if it is in + -- the form `function foo()` with no additional dots/colons in the + -- name chain. + local nameChain = stat.NameChain + local var; + if #nameChain == 1 then + -- If there is only one item in the name chain, then the first item + -- is a reference to a global variable. + var = addGlobalReference(nameChain[1].Source, function(name) + nameChain[1].Source = name + end) + else + var = referenceVariable(nameChain[1].Source, function(name) + nameChain[1].Source = name + end) + end + var.AssignedTo = true + pushScope() + for index, ident in pairs(stat.ArgList) do + addLocalVar(ident.Source, function(name) + ident.Source = name + end, { + Type = 'Argument', + Index = index, + }) + end + end, + Post = function() + popScope() + end, + } + visitor.GenericForStat = { + Pre = function(stat) + -- Generic fors need an extra scope holding the range variables + -- Need a custom visitor so that the generator expressions can be + -- visited before we push a scope, but the body can be visited + -- after we push a scope. + for _, ex in pairs(stat.GeneratorList) do + VisitAst(ex, visitor) + end + pushScope() + for index, ident in pairs(stat.VarList) do + addLocalVar(ident.Source, function(name) + ident.Source = name + end, { + Type = 'ForRange', + Index = index, + }) + end + VisitAst(stat.Body, visitor) + popScope() + return true -- Custom visit + end, + } + visitor.NumericForStat = { + Pre = function(stat) + -- Numeric fors need an extra scope holding the range variables + -- Need a custom visitor so that the generator expressions can be + -- visited before we push a scope, but the body can be visited + -- after we push a scope. + for _, ex in pairs(stat.RangeList) do + VisitAst(ex, visitor) + end + pushScope() + for index, ident in pairs(stat.VarList) do + addLocalVar(ident.Source, function(name) + ident.Source = name + end, { + Type = 'ForRange', + Index = index, + }) + end + VisitAst(stat.Body, visitor) + popScope() + return true -- Custom visit + end, + } + visitor.AssignmentStat = { + Post = function(stat) + -- For an assignment statement we need to mark the + -- "assigned to" flag on variables. + for _, ex in pairs(stat.Lhs) do + if ex.Variable then + ex.Variable.AssignedTo = true + end + end + end, + } + + VisitAst(ast, visitor) + + return globalVars, popScope() +end + +-- Prints out an AST to a string +local function PrintAst(ast) + local printStat, printExpr; + local str = {} + + local function printt(tk) + if not tk.LeadingWhite or not tk.Source then + error("Bad token: " .. FormatTable(tk)) + end + str[#str + 1] = tk.LeadingWhite + str[#str + 1] = tk.Source + end + + printExpr = function(expr) + if expr.Type == 'BinopExpr' then + printExpr(expr.Lhs) + printt(expr.Token_Op) + printExpr(expr.Rhs) + elseif expr.Type == 'UnopExpr' then + printt(expr.Token_Op) + printExpr(expr.Rhs) + elseif expr.Type == 'NumberLiteral' or expr.Type == 'StringLiteral' or + expr.Type == 'NilLiteral' or expr.Type == 'BooleanLiteral' or + expr.Type == 'VargLiteral' + then + -- Just print the token + printt(expr.Token) + elseif expr.Type == 'FieldExpr' then + printExpr(expr.Base) + printt(expr.Token_Dot) + printt(expr.Field) + elseif expr.Type == 'IndexExpr' then + printExpr(expr.Base) + printt(expr.Token_OpenBracket) + printExpr(expr.Index) + printt(expr.Token_CloseBracket) + elseif expr.Type == 'MethodExpr' or expr.Type == 'CallExpr' then + printExpr(expr.Base) + if expr.Type == 'MethodExpr' then + printt(expr.Token_Colon) + printt(expr.Method) + end + if expr.FunctionArguments.CallType == 'StringCall' then + printt(expr.FunctionArguments.Token) + elseif expr.FunctionArguments.CallType == 'ArgCall' then + printt(expr.FunctionArguments.Token_OpenParen) + for index, argExpr in pairs(expr.FunctionArguments.ArgList) do + printExpr(argExpr) + local sep = expr.FunctionArguments.Token_CommaList[index] + if sep then + printt(sep) + end + end + printt(expr.FunctionArguments.Token_CloseParen) + elseif expr.FunctionArguments.CallType == 'TableCall' then + printExpr(expr.FunctionArguments.TableExpr) + end + elseif expr.Type == 'FunctionLiteral' then + printt(expr.Token_Function) + printt(expr.Token_OpenParen) + for index, arg in pairs(expr.ArgList) do + printt(arg) + local comma = expr.Token_ArgCommaList[index] + if comma then + printt(comma) + end + end + printt(expr.Token_CloseParen) + printStat(expr.Body) + printt(expr.Token_End) + elseif expr.Type == 'VariableExpr' then + printt(expr.Token) + elseif expr.Type == 'ParenExpr' then + printt(expr.Token_OpenParen) + printExpr(expr.Expression) + printt(expr.Token_CloseParen) + elseif expr.Type == 'TableLiteral' then + printt(expr.Token_OpenBrace) + for index, entry in pairs(expr.EntryList) do + if entry.EntryType == 'Field' then + printt(entry.Field) + printt(entry.Token_Equals) + printExpr(entry.Value) + elseif entry.EntryType == 'Index' then + printt(entry.Token_OpenBracket) + printExpr(entry.Index) + printt(entry.Token_CloseBracket) + printt(entry.Token_Equals) + printExpr(entry.Value) + elseif entry.EntryType == 'Value' then + printExpr(entry.Value) + else + assert(false, "unreachable") + end + local sep = expr.Token_SeparatorList[index] + if sep then + printt(sep) + end + end + printt(expr.Token_CloseBrace) + else + assert(false, "unreachable, type: " .. expr.Type .. ":" .. FormatTable(expr)) + end + end + + printStat = function(stat) + if stat.Type == 'StatList' then + for index, ch in pairs(stat.StatementList) do + printStat(ch) + if stat.SemicolonList[index] then + printt(stat.SemicolonList[index]) + end + end + elseif stat.Type == 'BreakStat' then + printt(stat.Token_Break) + elseif stat.Type == 'ReturnStat' then + printt(stat.Token_Return) + for index, expr in pairs(stat.ExprList) do + printExpr(expr) + if stat.Token_CommaList[index] then + printt(stat.Token_CommaList[index]) + end + end + elseif stat.Type == 'LocalVarStat' then + printt(stat.Token_Local) + for index, var in pairs(stat.VarList) do + printt(var) + local comma = stat.Token_VarCommaList[index] + if comma then + printt(comma) + end + end + if stat.Token_Equals then + printt(stat.Token_Equals) + for index, expr in pairs(stat.ExprList) do + printExpr(expr) + local comma = stat.Token_ExprCommaList[index] + if comma then + printt(comma) + end + end + end + elseif stat.Type == 'LocalFunctionStat' then + printt(stat.Token_Local) + printt(stat.FunctionStat.Token_Function) + printt(stat.FunctionStat.NameChain[1]) + printt(stat.FunctionStat.Token_OpenParen) + for index, arg in pairs(stat.FunctionStat.ArgList) do + printt(arg) + local comma = stat.FunctionStat.Token_ArgCommaList[index] + if comma then + printt(comma) + end + end + printt(stat.FunctionStat.Token_CloseParen) + printStat(stat.FunctionStat.Body) + printt(stat.FunctionStat.Token_End) + elseif stat.Type == 'FunctionStat' then + printt(stat.Token_Function) + for index, part in pairs(stat.NameChain) do + printt(part) + local sep = stat.Token_NameChainSeparator[index] + if sep then + printt(sep) + end + end + printt(stat.Token_OpenParen) + for index, arg in pairs(stat.ArgList) do + printt(arg) + local comma = stat.Token_ArgCommaList[index] + if comma then + printt(comma) + end + end + printt(stat.Token_CloseParen) + printStat(stat.Body) + printt(stat.Token_End) + elseif stat.Type == 'RepeatStat' then + printt(stat.Token_Repeat) + printStat(stat.Body) + printt(stat.Token_Until) + printExpr(stat.Condition) + elseif stat.Type == 'GenericForStat' then + printt(stat.Token_For) + for index, var in pairs(stat.VarList) do + printt(var) + local sep = stat.Token_VarCommaList[index] + if sep then + printt(sep) + end + end + printt(stat.Token_In) + for index, expr in pairs(stat.GeneratorList) do + printExpr(expr) + local sep = stat.Token_GeneratorCommaList[index] + if sep then + printt(sep) + end + end + printt(stat.Token_Do) + printStat(stat.Body) + printt(stat.Token_End) + elseif stat.Type == 'NumericForStat' then + printt(stat.Token_For) + for index, var in pairs(stat.VarList) do + printt(var) + local sep = stat.Token_VarCommaList[index] + if sep then + printt(sep) + end + end + printt(stat.Token_Equals) + for index, expr in pairs(stat.RangeList) do + printExpr(expr) + local sep = stat.Token_RangeCommaList[index] + if sep then + printt(sep) + end + end + printt(stat.Token_Do) + printStat(stat.Body) + printt(stat.Token_End) + elseif stat.Type == 'WhileStat' then + printt(stat.Token_While) + printExpr(stat.Condition) + printt(stat.Token_Do) + printStat(stat.Body) + printt(stat.Token_End) + elseif stat.Type == 'DoStat' then + printt(stat.Token_Do) + printStat(stat.Body) + printt(stat.Token_End) + elseif stat.Type == 'IfStat' then + printt(stat.Token_If) + printExpr(stat.Condition) + printt(stat.Token_Then) + printStat(stat.Body) + for _, clause in pairs(stat.ElseClauseList) do + printt(clause.Token) + if clause.Condition then + printExpr(clause.Condition) + printt(clause.Token_Then) + end + printStat(clause.Body) + end + printt(stat.Token_End) + elseif stat.Type == 'CallExprStat' then + printExpr(stat.Expression) + elseif stat.Type == 'AssignmentStat' then + for index, ex in pairs(stat.Lhs) do + printExpr(ex) + local sep = stat.Token_LhsSeparatorList[index] + if sep then + printt(sep) + end + end + printt(stat.Token_Equals) + for index, ex in pairs(stat.Rhs) do + printExpr(ex) + local sep = stat.Token_RhsSeparatorList[index] + if sep then + printt(sep) + end + end + else + assert(false, "unreachable") + end + end + + printStat(ast) + return table.concat(str) +end + +-- Adds / removes whitespace in an AST to put it into a "standard formatting" +local function FormatAst(ast) + local formatStat, formatExpr; + + local currentIndent = 0 + + local function applyIndent(token) + local indentString = '\n' .. ('\t'):rep(currentIndent) + if token.LeadingWhite == '' or (token.LeadingWhite:sub(- #indentString, -1) ~= indentString) then + -- Trim existing trailing whitespace on LeadingWhite + -- Trim trailing tabs and spaces, and up to one newline + token.LeadingWhite = token.LeadingWhite:gsub("\n?[\t ]*$", "") + token.LeadingWhite = token.LeadingWhite .. indentString + end + end + + local function indent() + currentIndent = currentIndent + 1 + end + + local function undent() + currentIndent = currentIndent - 1 + assert(currentIndent >= 0, "Undented too far") + end + + local function leadingChar(tk) + if #tk.LeadingWhite > 0 then + return tk.LeadingWhite:sub(1, 1) + else + return tk.Source:sub(1, 1) + end + end + + local function padToken(tk) + if not WhiteChars[leadingChar(tk)] then + tk.LeadingWhite = ' ' .. tk.LeadingWhite + end + end + + local function padExpr(expr) + padToken(expr:GetFirstToken()) + end + + local function formatBody(openToken, bodyStat, closeToken) + indent() + formatStat(bodyStat) + undent() + applyIndent(closeToken) + end + + formatExpr = function(expr) + if expr.Type == 'BinopExpr' then + formatExpr(expr.Lhs) + formatExpr(expr.Rhs) + if expr.Token_Op.Source == '..' then + -- No padding on .. + else + padExpr(expr.Rhs) + padToken(expr.Token_Op) + end + elseif expr.Type == 'UnopExpr' then + formatExpr(expr.Rhs) + --(expr.Token_Op) + elseif expr.Type == 'NumberLiteral' or expr.Type == 'StringLiteral' or + expr.Type == 'NilLiteral' or expr.Type == 'BooleanLiteral' or + expr.Type == 'VargLiteral' + then + -- Nothing to do + --(expr.Token) + elseif expr.Type == 'FieldExpr' then + formatExpr(expr.Base) + --(expr.Token_Dot) + --(expr.Field) + elseif expr.Type == 'IndexExpr' then + formatExpr(expr.Base) + formatExpr(expr.Index) + --(expr.Token_OpenBracket) + --(expr.Token_CloseBracket) + elseif expr.Type == 'MethodExpr' or expr.Type == 'CallExpr' then + formatExpr(expr.Base) + if expr.Type == 'MethodExpr' then + --(expr.Token_Colon) + --(expr.Method) + end + if expr.FunctionArguments.CallType == 'StringCall' then + --(expr.FunctionArguments.Token) + elseif expr.FunctionArguments.CallType == 'ArgCall' then + --(expr.FunctionArguments.Token_OpenParen) + for index, argExpr in pairs(expr.FunctionArguments.ArgList) do + formatExpr(argExpr) + if index > 1 then + padExpr(argExpr) + end + local sep = expr.FunctionArguments.Token_CommaList[index] + if sep then + --(sep) + end + end + --(expr.FunctionArguments.Token_CloseParen) + elseif expr.FunctionArguments.CallType == 'TableCall' then + formatExpr(expr.FunctionArguments.TableExpr) + end + elseif expr.Type == 'FunctionLiteral' then + --(expr.Token_Function) + --(expr.Token_OpenParen) + for index, arg in pairs(expr.ArgList) do + --(arg) + if index > 1 then + padToken(arg) + end + local comma = expr.Token_ArgCommaList[index] + if comma then + --(comma) + end + end + --(expr.Token_CloseParen) + formatBody(expr.Token_CloseParen, expr.Body, expr.Token_End) + elseif expr.Type == 'VariableExpr' then + --(expr.Token) + elseif expr.Type == 'ParenExpr' then + formatExpr(expr.Expression) + --(expr.Token_OpenParen) + --(expr.Token_CloseParen) + elseif expr.Type == 'TableLiteral' then + --(expr.Token_OpenBrace) + if #expr.EntryList == 0 then + -- Nothing to do + else + indent() + for index, entry in pairs(expr.EntryList) do + if entry.EntryType == 'Field' then + applyIndent(entry.Field) + padToken(entry.Token_Equals) + formatExpr(entry.Value) + padExpr(entry.Value) + elseif entry.EntryType == 'Index' then + applyIndent(entry.Token_OpenBracket) + formatExpr(entry.Index) + --(entry.Token_CloseBracket) + padToken(entry.Token_Equals) + formatExpr(entry.Value) + padExpr(entry.Value) + elseif entry.EntryType == 'Value' then + formatExpr(entry.Value) + applyIndent(entry.Value:GetFirstToken()) + else + assert(false, "unreachable") + end + local sep = expr.Token_SeparatorList[index] + if sep then + --(sep) + end + end + undent() + applyIndent(expr.Token_CloseBrace) + end + --(expr.Token_CloseBrace) + else + assert(false, "unreachable, type: " .. expr.Type .. ":" .. FormatTable(expr)) + end + end + + formatStat = function(stat) + if stat.Type == 'StatList' then + for _, stat in pairs(stat.StatementList) do + formatStat(stat) + applyIndent(stat:GetFirstToken()) + end + elseif stat.Type == 'BreakStat' then + --(stat.Token_Break) + elseif stat.Type == 'ReturnStat' then + --(stat.Token_Return) + for index, expr in pairs(stat.ExprList) do + formatExpr(expr) + padExpr(expr) + if stat.Token_CommaList[index] then + --(stat.Token_CommaList[index]) + end + end + elseif stat.Type == 'LocalVarStat' then + --(stat.Token_Local) + for index, var in pairs(stat.VarList) do + padToken(var) + local comma = stat.Token_VarCommaList[index] + if comma then + --(comma) + end + end + if stat.Token_Equals then + padToken(stat.Token_Equals) + for index, expr in pairs(stat.ExprList) do + formatExpr(expr) + padExpr(expr) + local comma = stat.Token_ExprCommaList[index] + if comma then + --(comma) + end + end + end + elseif stat.Type == 'LocalFunctionStat' then + --(stat.Token_Local) + padToken(stat.FunctionStat.Token_Function) + padToken(stat.FunctionStat.NameChain[1]) + --(stat.FunctionStat.Token_OpenParen) + for index, arg in pairs(stat.FunctionStat.ArgList) do + if index > 1 then + padToken(arg) + end + local comma = stat.FunctionStat.Token_ArgCommaList[index] + if comma then + --(comma) + end + end + --(stat.FunctionStat.Token_CloseParen) + formatBody(stat.FunctionStat.Token_CloseParen, stat.FunctionStat.Body, stat.FunctionStat.Token_End) + elseif stat.Type == 'FunctionStat' then + --(stat.Token_Function) + for index, part in pairs(stat.NameChain) do + if index == 1 then + padToken(part) + end + local sep = stat.Token_NameChainSeparator[index] + if sep then + --(sep) + end + end + --(stat.Token_OpenParen) + for index, arg in pairs(stat.ArgList) do + if index > 1 then + padToken(arg) + end + local comma = stat.Token_ArgCommaList[index] + if comma then + --(comma) + end + end + --(stat.Token_CloseParen) + formatBody(stat.Token_CloseParen, stat.Body, stat.Token_End) + elseif stat.Type == 'RepeatStat' then + --(stat.Token_Repeat) + formatBody(stat.Token_Repeat, stat.Body, stat.Token_Until) + formatExpr(stat.Condition) + padExpr(stat.Condition) + elseif stat.Type == 'GenericForStat' then + --(stat.Token_For) + for index, var in pairs(stat.VarList) do + padToken(var) + local sep = stat.Token_VarCommaList[index] + if sep then + --(sep) + end + end + padToken(stat.Token_In) + for index, expr in pairs(stat.GeneratorList) do + formatExpr(expr) + padExpr(expr) + local sep = stat.Token_GeneratorCommaList[index] + if sep then + --(sep) + end + end + padToken(stat.Token_Do) + formatBody(stat.Token_Do, stat.Body, stat.Token_End) + elseif stat.Type == 'NumericForStat' then + --(stat.Token_For) + for index, var in pairs(stat.VarList) do + padToken(var) + local sep = stat.Token_VarCommaList[index] + if sep then + --(sep) + end + end + padToken(stat.Token_Equals) + for index, expr in pairs(stat.RangeList) do + formatExpr(expr) + padExpr(expr) + local sep = stat.Token_RangeCommaList[index] + if sep then + --(sep) + end + end + padToken(stat.Token_Do) + formatBody(stat.Token_Do, stat.Body, stat.Token_End) + elseif stat.Type == 'WhileStat' then + --(stat.Token_While) + formatExpr(stat.Condition) + padExpr(stat.Condition) + padToken(stat.Token_Do) + formatBody(stat.Token_Do, stat.Body, stat.Token_End) + elseif stat.Type == 'DoStat' then + --(stat.Token_Do) + formatBody(stat.Token_Do, stat.Body, stat.Token_End) + elseif stat.Type == 'IfStat' then + --(stat.Token_If) + formatExpr(stat.Condition) + padExpr(stat.Condition) + padToken(stat.Token_Then) + -- + local lastBodyOpen = stat.Token_Then + local lastBody = stat.Body + -- + for _, clause in pairs(stat.ElseClauseList) do + formatBody(lastBodyOpen, lastBody, clause.Token) + lastBodyOpen = clause.Token + -- + if clause.Condition then + formatExpr(clause.Condition) + padExpr(clause.Condition) + padToken(clause.Token_Then) + lastBodyOpen = clause.Token_Then + end + lastBody = clause.Body + end + -- + formatBody(lastBodyOpen, lastBody, stat.Token_End) + elseif stat.Type == 'CallExprStat' then + formatExpr(stat.Expression) + elseif stat.Type == 'AssignmentStat' then + for index, ex in pairs(stat.Lhs) do + formatExpr(ex) + if index > 1 then + padExpr(ex) + end + local sep = stat.Token_LhsSeparatorList[index] + if sep then + --(sep) + end + end + padToken(stat.Token_Equals) + for index, ex in pairs(stat.Rhs) do + formatExpr(ex) + padExpr(ex) + local sep = stat.Token_RhsSeparatorList[index] + if sep then + --(sep) + end + end + else + assert(false, "unreachable") + end + end + + formatStat(ast) +end + +-- Strips as much whitespace off of tokens in an AST as possible without causing problems +local function StripAst(ast) + local stripStat, stripExpr; + + local function stript(token) + token.LeadingWhite = '' + end + + -- Make to adjacent tokens as close as possible + local function joint(tokenA, tokenB) + -- Strip the second token's whitespace + stript(tokenB) + + -- Get the trailing A <-> leading B character pair + local lastCh = tokenA.Source:sub(-1, -1) + local firstCh = tokenB.Source:sub(1, 1) + + -- Cases to consider: + -- Touching minus signs -> comment: `- -42` -> `--42' is invalid + -- Touching words: `a b` -> `ab` is invalid + -- Touching digits: `2 3`, can't occurr in the Lua syntax as number literals aren't a primary expression + -- Abiguous syntax: `f(x)\n(x)()` is already disallowed, we can't cause a problem by removing newlines + + -- Figure out what separation is needed + if + (lastCh == '-' and firstCh == '-') or + (AllIdentChars[lastCh] and AllIdentChars[firstCh]) + then + tokenB.LeadingWhite = ' ' -- Use a separator + else + tokenB.LeadingWhite = '' -- Don't use a separator + end + end + + -- Join up a statement body and it's opening / closing tokens + local function bodyjoint(open, body, close) + stripStat(body) + stript(close) + local bodyFirst = body:GetFirstToken() + local bodyLast = body:GetLastToken() + if bodyFirst then + -- Body is non-empty, join body to open / close + joint(open, bodyFirst) + joint(bodyLast, close) + else + -- Body is empty, just join open and close token together + joint(open, close) + end + end + + stripExpr = function(expr) + if expr.Type == 'BinopExpr' then + stripExpr(expr.Lhs) + stript(expr.Token_Op) + stripExpr(expr.Rhs) + -- Handle the `a - -b` -/-> `a--b` case which would otherwise incorrectly generate a comment + -- Also handles operators "or" / "and" which definitely need joining logic in a bunch of cases + joint(expr.Token_Op, expr.Rhs:GetFirstToken()) + joint(expr.Lhs:GetLastToken(), expr.Token_Op) + elseif expr.Type == 'UnopExpr' then + stript(expr.Token_Op) + stripExpr(expr.Rhs) + -- Handle the `- -b` -/-> `--b` case which would otherwise incorrectly generate a comment + joint(expr.Token_Op, expr.Rhs:GetFirstToken()) + elseif expr.Type == 'NumberLiteral' or expr.Type == 'StringLiteral' or + expr.Type == 'NilLiteral' or expr.Type == 'BooleanLiteral' or + expr.Type == 'VargLiteral' + then + -- Just print the token + stript(expr.Token) + elseif expr.Type == 'FieldExpr' then + stripExpr(expr.Base) + stript(expr.Token_Dot) + stript(expr.Field) + elseif expr.Type == 'IndexExpr' then + stripExpr(expr.Base) + stript(expr.Token_OpenBracket) + stripExpr(expr.Index) + stript(expr.Token_CloseBracket) + elseif expr.Type == 'MethodExpr' or expr.Type == 'CallExpr' then + stripExpr(expr.Base) + if expr.Type == 'MethodExpr' then + stript(expr.Token_Colon) + stript(expr.Method) + end + if expr.FunctionArguments.CallType == 'StringCall' then + stript(expr.FunctionArguments.Token) + elseif expr.FunctionArguments.CallType == 'ArgCall' then + stript(expr.FunctionArguments.Token_OpenParen) + for index, argExpr in pairs(expr.FunctionArguments.ArgList) do + stripExpr(argExpr) + local sep = expr.FunctionArguments.Token_CommaList[index] + if sep then + stript(sep) + end + end + stript(expr.FunctionArguments.Token_CloseParen) + elseif expr.FunctionArguments.CallType == 'TableCall' then + stripExpr(expr.FunctionArguments.TableExpr) + end + elseif expr.Type == 'FunctionLiteral' then + stript(expr.Token_Function) + stript(expr.Token_OpenParen) + for index, arg in pairs(expr.ArgList) do + stript(arg) + local comma = expr.Token_ArgCommaList[index] + if comma then + stript(comma) + end + end + stript(expr.Token_CloseParen) + bodyjoint(expr.Token_CloseParen, expr.Body, expr.Token_End) + elseif expr.Type == 'VariableExpr' then + stript(expr.Token) + elseif expr.Type == 'ParenExpr' then + stript(expr.Token_OpenParen) + stripExpr(expr.Expression) + stript(expr.Token_CloseParen) + elseif expr.Type == 'TableLiteral' then + stript(expr.Token_OpenBrace) + for index, entry in pairs(expr.EntryList) do + if entry.EntryType == 'Field' then + stript(entry.Field) + stript(entry.Token_Equals) + stripExpr(entry.Value) + elseif entry.EntryType == 'Index' then + stript(entry.Token_OpenBracket) + stripExpr(entry.Index) + stript(entry.Token_CloseBracket) + stript(entry.Token_Equals) + stripExpr(entry.Value) + elseif entry.EntryType == 'Value' then + stripExpr(entry.Value) + else + assert(false, "unreachable") + end + local sep = expr.Token_SeparatorList[index] + if sep then + stript(sep) + end + end + stript(expr.Token_CloseBrace) + else + assert(false, "unreachable, type: " .. expr.Type .. ":" .. FormatTable(expr)) + end + end + + stripStat = function(stat) + if stat.Type == 'StatList' then + -- Strip all surrounding whitespace on statement lists along with separating whitespace + for i = 1, #stat.StatementList do + local chStat = stat.StatementList[i] + + -- Strip the statement and it's whitespace + stripStat(chStat) + stript(chStat:GetFirstToken()) + + -- If there was a last statement, join them appropriately + local lastChStat = stat.StatementList[i - 1] + if lastChStat then + -- See if we can remove a semi-colon, the only case where we can't is if + -- this and the last statement have a `);(` pair, where removing the semi-colon + -- would introduce ambiguous syntax. + if stat.SemicolonList[i - 1] and + (lastChStat:GetLastToken().Source ~= ')' or chStat:GetFirstToken().Source ~= ')') + then + stat.SemicolonList[i - 1] = nil + end + + -- If there isn't a semi-colon, we should safely join the two statements + -- (If there is one, then no whitespace leading chStat is always okay) + if not stat.SemicolonList[i - 1] then + joint(lastChStat:GetLastToken(), chStat:GetFirstToken()) + end + end + end + + -- A semi-colon is never needed on the last stat in a statlist: + stat.SemicolonList[#stat.StatementList] = nil + + -- The leading whitespace on the statlist should be stripped + if #stat.StatementList > 0 then + stript(stat.StatementList[1]:GetFirstToken()) + end + elseif stat.Type == 'BreakStat' then + stript(stat.Token_Break) + elseif stat.Type == 'ReturnStat' then + stript(stat.Token_Return) + for index, expr in pairs(stat.ExprList) do + stripExpr(expr) + if stat.Token_CommaList[index] then + stript(stat.Token_CommaList[index]) + end + end + if #stat.ExprList > 0 then + joint(stat.Token_Return, stat.ExprList[1]:GetFirstToken()) + end + elseif stat.Type == 'LocalVarStat' then + stript(stat.Token_Local) + for index, var in pairs(stat.VarList) do + if index == 1 then + joint(stat.Token_Local, var) + else + stript(var) + end + local comma = stat.Token_VarCommaList[index] + if comma then + stript(comma) + end + end + if stat.Token_Equals then + stript(stat.Token_Equals) + for index, expr in pairs(stat.ExprList) do + stripExpr(expr) + local comma = stat.Token_ExprCommaList[index] + if comma then + stript(comma) + end + end + end + elseif stat.Type == 'LocalFunctionStat' then + stript(stat.Token_Local) + joint(stat.Token_Local, stat.FunctionStat.Token_Function) + joint(stat.FunctionStat.Token_Function, stat.FunctionStat.NameChain[1]) + joint(stat.FunctionStat.NameChain[1], stat.FunctionStat.Token_OpenParen) + for index, arg in pairs(stat.FunctionStat.ArgList) do + stript(arg) + local comma = stat.FunctionStat.Token_ArgCommaList[index] + if comma then + stript(comma) + end + end + stript(stat.FunctionStat.Token_CloseParen) + bodyjoint(stat.FunctionStat.Token_CloseParen, stat.FunctionStat.Body, stat.FunctionStat.Token_End) + elseif stat.Type == 'FunctionStat' then + stript(stat.Token_Function) + for index, part in pairs(stat.NameChain) do + if index == 1 then + joint(stat.Token_Function, part) + else + stript(part) + end + local sep = stat.Token_NameChainSeparator[index] + if sep then + stript(sep) + end + end + stript(stat.Token_OpenParen) + for index, arg in pairs(stat.ArgList) do + stript(arg) + local comma = stat.Token_ArgCommaList[index] + if comma then + stript(comma) + end + end + stript(stat.Token_CloseParen) + bodyjoint(stat.Token_CloseParen, stat.Body, stat.Token_End) + elseif stat.Type == 'RepeatStat' then + stript(stat.Token_Repeat) + bodyjoint(stat.Token_Repeat, stat.Body, stat.Token_Until) + stripExpr(stat.Condition) + joint(stat.Token_Until, stat.Condition:GetFirstToken()) + elseif stat.Type == 'GenericForStat' then + stript(stat.Token_For) + for index, var in pairs(stat.VarList) do + if index == 1 then + joint(stat.Token_For, var) + else + stript(var) + end + local sep = stat.Token_VarCommaList[index] + if sep then + stript(sep) + end + end + joint(stat.VarList[#stat.VarList], stat.Token_In) + for index, expr in pairs(stat.GeneratorList) do + stripExpr(expr) + if index == 1 then + joint(stat.Token_In, expr:GetFirstToken()) + end + local sep = stat.Token_GeneratorCommaList[index] + if sep then + stript(sep) + end + end + joint(stat.GeneratorList[#stat.GeneratorList]:GetLastToken(), stat.Token_Do) + bodyjoint(stat.Token_Do, stat.Body, stat.Token_End) + elseif stat.Type == 'NumericForStat' then + stript(stat.Token_For) + for index, var in pairs(stat.VarList) do + if index == 1 then + joint(stat.Token_For, var) + else + stript(var) + end + local sep = stat.Token_VarCommaList[index] + if sep then + stript(sep) + end + end + joint(stat.VarList[#stat.VarList], stat.Token_Equals) + for index, expr in pairs(stat.RangeList) do + stripExpr(expr) + if index == 1 then + joint(stat.Token_Equals, expr:GetFirstToken()) + end + local sep = stat.Token_RangeCommaList[index] + if sep then + stript(sep) + end + end + joint(stat.RangeList[#stat.RangeList]:GetLastToken(), stat.Token_Do) + bodyjoint(stat.Token_Do, stat.Body, stat.Token_End) + elseif stat.Type == 'WhileStat' then + stript(stat.Token_While) + stripExpr(stat.Condition) + stript(stat.Token_Do) + joint(stat.Token_While, stat.Condition:GetFirstToken()) + joint(stat.Condition:GetLastToken(), stat.Token_Do) + bodyjoint(stat.Token_Do, stat.Body, stat.Token_End) + elseif stat.Type == 'DoStat' then + stript(stat.Token_Do) + stript(stat.Token_End) + bodyjoint(stat.Token_Do, stat.Body, stat.Token_End) + elseif stat.Type == 'IfStat' then + stript(stat.Token_If) + stripExpr(stat.Condition) + joint(stat.Token_If, stat.Condition:GetFirstToken()) + joint(stat.Condition:GetLastToken(), stat.Token_Then) + -- + local lastBodyOpen = stat.Token_Then + local lastBody = stat.Body + -- + for _, clause in pairs(stat.ElseClauseList) do + bodyjoint(lastBodyOpen, lastBody, clause.Token) + lastBodyOpen = clause.Token + -- + if clause.Condition then + stripExpr(clause.Condition) + joint(clause.Token, clause.Condition:GetFirstToken()) + joint(clause.Condition:GetLastToken(), clause.Token_Then) + lastBodyOpen = clause.Token_Then + end + stripStat(clause.Body) + lastBody = clause.Body + end + -- + bodyjoint(lastBodyOpen, lastBody, stat.Token_End) + elseif stat.Type == 'CallExprStat' then + stripExpr(stat.Expression) + elseif stat.Type == 'AssignmentStat' then + for index, ex in pairs(stat.Lhs) do + stripExpr(ex) + local sep = stat.Token_LhsSeparatorList[index] + if sep then + stript(sep) + end + end + stript(stat.Token_Equals) + for index, ex in pairs(stat.Rhs) do + stripExpr(ex) + local sep = stat.Token_RhsSeparatorList[index] + if sep then + stript(sep) + end + end + else + assert(false, "unreachable") + end + end + + stripStat(ast) +end + +local idGen = 0 +local VarDigits = {} +for i = ('a'):byte(), ('z'):byte() do table.insert(VarDigits, string.char(i)) end +for i = ('A'):byte(), ('Z'):byte() do table.insert(VarDigits, string.char(i)) end +for i = ('0'):byte(), ('9'):byte() do table.insert(VarDigits, string.char(i)) end +table.insert(VarDigits, '_') +local VarStartDigits = {} +for i = ('a'):byte(), ('z'):byte() do table.insert(VarStartDigits, string.char(i)) end +for i = ('A'):byte(), ('Z'):byte() do table.insert(VarStartDigits, string.char(i)) end +local function indexToVarName(index) + local id = '' + local d = index % #VarStartDigits + index = (index - d) / #VarStartDigits + id = id .. VarStartDigits[d + 1] + while index > 0 do + local d = index % #VarDigits + index = (index - d) / #VarDigits + id = id .. VarDigits[d + 1] + end + return id +end +local function genNextVarName() + local varToUse = idGen + idGen = idGen + 1 + return indexToVarName(varToUse) +end +local function genVarName() + local varName = '' + repeat + varName = genNextVarName() + until not Keywords[varName] + return varName +end +local function MinifyVariables(globalScope, rootScope) + -- externalGlobals is a set of global variables that have not been assigned to, that is + -- global variables defined "externally to the script". We are not going to be renaming + -- those, and we have to make sure that we don't collide with them when renaming + -- things so we keep track of them in this set. + local externalGlobals = {} + + -- First we want to rename all of the variables to unique temoraries, so that we can + -- easily use the scope::GetVar function to check whether renames are valid. + local temporaryIndex = 0 + for _, var in pairs(globalScope) do + if var.AssignedTo then + var:Rename('_TMP_' .. temporaryIndex .. '_') + temporaryIndex = temporaryIndex + 1 + else + -- Not assigned to, external global + externalGlobals[var.Name] = true + end + end + local function temporaryRename(scope) + for _, var in pairs(scope.VariableList) do + var:Rename('_TMP_' .. temporaryIndex .. '_') + temporaryIndex = temporaryIndex + 1 + end + for _, childScope in pairs(scope.ChildScopeList) do + temporaryRename(childScope) + end + end + + -- Now we go through renaming, first do globals, we probably want them + -- to have shorter names in general. + -- TODO: Rename all vars based on frequency patterns, giving variables + -- used more shorter names. + local nextFreeNameIndex = 0 + for _, var in pairs(globalScope) do + if var.AssignedTo then + local varName = '' + repeat + varName = indexToVarName(nextFreeNameIndex) + nextFreeNameIndex = nextFreeNameIndex + 1 + until not Keywords[varName] and not externalGlobals[varName] + var:Rename(varName) + end + end + + -- Now rename all local vars + rootScope.FirstFreeName = nextFreeNameIndex + local function doRenameScope(scope) + for _, var in pairs(scope.VariableList) do + local varName = '' + repeat + varName = indexToVarName(scope.FirstFreeName) + scope.FirstFreeName = scope.FirstFreeName + 1 + until not Keywords[varName] and not externalGlobals[varName] + var:Rename(varName) + end + for _, childScope in pairs(scope.ChildScopeList) do + childScope.FirstFreeName = scope.FirstFreeName + doRenameScope(childScope) + end + end + doRenameScope(rootScope) +end + +local function BeautifyVariables(globalScope, rootScope) + local externalGlobals = {} + for _, var in pairs(globalScope) do + if not var.AssignedTo then + externalGlobals[var.Name] = true + end + end + + local localNumber = 1 + local globalNumber = 1 + + local function setVarName(var, name) + var.Name = name + for _, setter in pairs(var.RenameList) do + setter(name) + end + end + + for _, var in pairs(globalScope) do + if var.AssignedTo then + setVarName(var, 'G_' .. globalNumber) + globalNumber = globalNumber + 1 + end + end + + local function modify(scope) + for _, var in pairs(scope.VariableList) do + local name = 'L_' .. localNumber .. '_' + if var.Info.Type == 'Argument' then + name = name .. 'arg' .. var.Info.Index + elseif var.Info.Type == 'LocalFunction' then + name = name .. 'func' + elseif var.Info.Type == 'ForRange' then + name = name .. 'forvar' .. var.Info.Index + end + setVarName(var, name) + localNumber = localNumber + 1 + end + for _, scope in pairs(scope.ChildScopeList) do + modify(scope) + end + end + modify(rootScope) +end + +local function validateCode(code, validate) + if validate then + local func,err = load(code, "@minifyvalidation", "t", {}) + if not func then + error(err) + end + end +end + +function lib.minify(src, ignoreValidation) + validateCode(src, not ignoreValidation) + local ast = CreateLuaParser(src) + local global_scope, root_scope = AddVariableInfo(ast) + MinifyVariables(global_scope, root_scope) + StripAst(ast) + local out = PrintAst(ast) + validateCode(out, not ignoreValidation) + return out +end + +function lib.beautify(src, ignoreValidation) + validateCode(src, ignoreValidation) + local ast = CreateLuaParser(src) + local global_scope, root_scope = AddVariableInfo(ast) + BeautifyVariables(global_scope, root_scope) + FormatAst(ast) + local out = PrintAst(ast) + validateCode(out, not ignoreValidation) + return out +end + +return lib diff --git a/Src/pid/data/lib/pid.lua b/Src/pid/data/lib/pid.lua new file mode 100644 index 0000000..2f6a823 --- /dev/null +++ b/Src/pid/data/lib/pid.lua @@ -0,0 +1,136 @@ +--:Minify:-- + +local pid = {} +pid.__index = pid + +local function clamp(value, minimum, maximum) + if minimum and value < minimum then + return minimum + end + if maximum and value > maximum then + return maximum + end + return value +end + +local function assertNumber(value, name) + if type(value) ~= "number" then + error("pid: " .. name .. " must be a number") + end + return value +end + +function pid.new(kp, ki, kd, options) + assertNumber(kp, "kp") + assertNumber(ki, "ki") + assertNumber(kd, "kd") + + options = options or {} + + local controller = setmetatable({ + kp = kp, + ki = ki, + kd = kd, + setpoint = options.setpoint or 0, + outputMin = options.outputMin, + outputMax = options.outputMax, + integralMin = options.integralMin, + integralMax = options.integralMax, + lastError = 0, + integral = 0, + lastMeasurement = nil, + lastOutput = 0, + lastTime = nil, + }, pid) + + return controller +end + +function pid:reset() + self.lastError = 0 + self.integral = 0 + self.lastMeasurement = nil + self.lastOutput = 0 + self.lastTime = nil +end + +function pid:setSetpoint(setpoint) + assertNumber(setpoint, "setpoint") + self.setpoint = setpoint +end + +function pid:setCoefficients(kp, ki, kd) + assertNumber(kp, "kp") + assertNumber(ki, "ki") + assertNumber(kd, "kd") + self.kp = kp + self.ki = ki + self.kd = kd +end + +function pid:setOutputLimits(minimum, maximum) + if minimum ~= nil then assertNumber(minimum, "outputMin") end + if maximum ~= nil then assertNumber(maximum, "outputMax") end + if minimum and maximum and minimum > maximum then + error("pid: outputMin must be <= outputMax") + end + self.outputMin = minimum + self.outputMax = maximum +end + +function pid:setIntegralLimits(minimum, maximum) + if minimum ~= nil then assertNumber(minimum, "integralMin") end + if maximum ~= nil then assertNumber(maximum, "integralMax") end + if minimum and maximum and minimum > maximum then + error("pid: integralMin must be <= integralMax") + end + self.integralMin = minimum + self.integralMax = maximum +end + +function pid:update(measurement, dt) + assertNumber(measurement, "measurement") + assertNumber(dt, "dt") + if dt <= 0 then + error("pid: dt must be greater than zero") + end + + local errorValue = self.setpoint - measurement + self.integral = clamp(self.integral + errorValue * dt, self.integralMin, self.integralMax) + local derivative = 0 + if self.lastTime ~= nil then + derivative = (errorValue - self.lastError) / dt + end + + local output = self.kp * errorValue + self.ki * self.integral + self.kd * derivative + output = clamp(output, self.outputMin, self.outputMax) + + self.lastError = errorValue + self.lastMeasurement = measurement + self.lastOutput = output + self.lastTime = (self.lastTime or 0) + dt + + return output +end + +function pid:compute(measurement, dt) + return self:update(measurement, dt) +end + +function pid:getState() + return { + setpoint = self.setpoint, + kp = self.kp, + ki = self.ki, + kd = self.kd, + integral = self.integral, + lastError = self.lastError, + lastOutput = self.lastOutput, + } +end + +function pid:resetIntegral() + self.integral = 0 +end + +return pid diff --git a/Src/sysinit/control/symlinks.json b/Src/sysinit/control/symlinks.json new file mode 100644 index 0000000..ee2740f --- /dev/null +++ b/Src/sysinit/control/symlinks.json @@ -0,0 +1,3 @@ +{ + "/sbin/init": "/usr/lib/sysinit/sysinit" +} \ No newline at end of file diff --git a/Src/sysinit/data/usr/lib/sysinit/sysinit b/Src/sysinit/data/usr/lib/sysinit/sysinit index 8e5859b..c8cd61d 100644 --- a/Src/sysinit/data/usr/lib/sysinit/sysinit +++ b/Src/sysinit/data/usr/lib/sysinit/sysinit @@ -2,6 +2,7 @@ local kernel=... local fs=require("fs") kernel.log("Sysinit started...") +kernel.saveLog() for i,v in pairs(kernel.processes) do kernel.log("Spawning kernel task "..i) @@ -41,6 +42,7 @@ for i,v in ipairs(files) do end end end +kernel.saveLog() while true do sleep(5) diff --git a/build.py b/build.py index 5715b27..7513b75 100644 --- a/build.py +++ b/build.py @@ -1,271 +1,272 @@ -#!/usr/bin/env python3 -""" -Usage: - python build.py [--arch cct|oc] [--release|--dev] - -Targets: - build - build-mini - build-micro - build-test - build-mini-test - build-micro-test - clean - prod - prod-mini - -Arch flags: - --arch cct - --arch oc - -Release flags: - --release - --dev -""" - -import sys -import shutil -import argparse -import subprocess -import json -from pathlib import Path -from typing import Union - -PROJECT_ROOT = Path(__file__).resolve().parent -SRC_ROOT = PROJECT_ROOT / "Src" -TEST_ROOT = PROJECT_ROOT / "Test" -BUILD_ROOT = PROJECT_ROOT / "Build" -PROD_ROOT = PROJECT_ROOT / "prod" - -ARCH_BOOT_DIR = { - "cct": Path("boot") / "cct", - "oc": Path("boot") / "oc", -} - - -def clean(): - if BUILD_ROOT.exists(): - print(f"Removing {BUILD_ROOT} ...") - shutil.rmtree(BUILD_ROOT) - else: - print("Nothing to clean.") - -def cleanprod(): - if PROD_ROOT.exists(): - print(f"Removing {PROD_ROOT} ...") - shutil.rmtree(PROD_ROOT) - else: - print("Nothing to clean.") - - -def has_minify_header(path: Path) -> bool: - try: - with path.open("r", encoding="utf-8", errors="ignore") as f: - for _ in range(3): - if "--:Minify:--" in f.readline(): - return True - except OSError: - pass - return False - - -def minify_file(src: Path) -> str: - result = subprocess.run( - ["luamin.cmd", "-f", str(src)], - capture_output=True, - text=True - ) - if result.returncode != 0: - print(f" ! luamin failed: {result.stderr.strip()}", file=sys.stderr) - sys.exit(1) - return result.stdout - - -def compress_lz4(data: bytes) -> bytes: - return lz4.frame.compress(data) - - -def process_root(src_root: Path, out_root: Path, minify: bool, micro: bool, arch:Union[str, None], prod:bool): - print(f"Building from {src_root}") - print(f"Output to {out_root}") - print() - - for pkg_dir in sorted(src_root.iterdir()): - if not pkg_dir.is_dir(): - continue - - if pkg_dir.name[:18] == "Hyperion-firmware-": - if pkg_dir.name != f"Hyperion-firmware-{arch}": - if prod != True: - continue - - data_dir=pkg_dir / "data" - - if not data_dir.is_dir(): - continue - - print(f"== Package: {pkg_dir.name} ==") - - for src in sorted(data_dir.rglob("*")): - if not src.is_file(): - continue - - rel = src.relative_to(data_dir) - - dst = out_root / rel - if prod: - dst = out_root / pkg_dir.name / rel - - dst.parent.mkdir(parents=True, exist_ok=True) - - print(f" Processing: {src.relative_to(src_root)}") - - if has_minify_header(src): - if minify: - print(" > Minifying") - content = minify_file(src) - if micro: - print(" > LZ4 compressing") - compressed = compress_lz4(content.encode("utf-8")) - dst.write_bytes(compressed) - else: - dst.write_text(content, encoding="utf-8") - else: - print(" > Copying") - shutil.copy2(src, dst) - else: - print(" > Copying") - shutil.copy2(src, dst) - - print() - - -def install_bootloader(arch: str, release: bool): - boot_dir = BUILD_ROOT / "$" / ARCH_BOOT_DIR[arch] - eeprom = boot_dir / "eeprom" - - eeprom_dst_name = "startup.lua" if release else "eeprom" - print(f" Installing: eeprom -> Build/{eeprom_dst_name}") - shutil.copy2(eeprom, BUILD_ROOT / eeprom_dst_name) - - -def run_build(minify: bool, micro: bool, include_test: bool, arch: Union[str, None], release: bool, prod: bool): - clean() - BUILD_ROOT.mkdir() - if prod: - cleanprod() - PROD_ROOT.mkdir() - - out_root = BUILD_ROOT / "$" if arch else BUILD_ROOT - - process_root(SRC_ROOT, out_root, minify, micro, arch, False) - if prod: - process_root(SRC_ROOT, PROD_ROOT, minify, micro, arch, True) - - if include_test: - process_root(TEST_ROOT, out_root, minify, micro) - - if arch: - print("Installing bootloader files ...") - install_bootloader(arch, release) - print() - - -def _make_firstboot_kmod(users): - lines = [] - lines.append("local kernel = ...") - lines.append("local auth = kernel.auth") - lines.append("") - - for username, password in users: - u = username.replace("\\", "\\\\").replace("'", "\\'") - p = password.replace("\\", "\\\\").replace("'", "\\'") - - if username == "root": - lines.append("do") - lines.append(" local ok, err = auth.setPassword(0, '" + p + "')") - lines.append(" if ok then") - lines.append(" kernel.log('FIRSTBOOT: root password set')") - lines.append(" else") - lines.append(" kernel.log('FIRSTBOOT: root password error: ' .. tostring(err), 'ERROR')") - lines.append(" end") - lines.append("end") - else: - lines.append("do") - lines.append(" local uid, err = auth.newUser('" + u + "', '" + p + "')") - lines.append(" if uid then") - lines.append(" kernel.log('FIRSTBOOT: created user " + u + " uid=' .. tostring(uid))") - lines.append(" else") - lines.append(" kernel.log('FIRSTBOOT: failed to create user " + u + ": ' .. tostring(err), 'ERROR')") - lines.append(" end") - lines.append("end") - lines.append("") - - lines.append("do") - lines.append(" local ok, err = pcall(function()") - lines.append(" kernel.vfs.remove('/lib/modules/Hyperion/50_firstboot_users.kmod')") - lines.append(" end)") - lines.append(" if not ok then") - lines.append(" kernel.log('FIRSTBOOT: could not self-delete: ' .. tostring(err), 'WARN')") - lines.append(" end") - lines.append("end") - - return "\n".join(lines) + "\n" - - -def inject_makeusers(users, arch): - base = BUILD_ROOT / "$" if arch else BUILD_ROOT - kmod_path = base / "lib" / "modules" / "Hyperion" / "50_firstboot_users.kmod" - kmod_path.parent.mkdir(parents=True, exist_ok=True) - kmod_path.write_text(_make_firstboot_kmod(users), encoding="utf-8") - print(" Wrote first-boot user setup -> " + str(kmod_path.relative_to(BUILD_ROOT))) - - -def main(): - parser = argparse.ArgumentParser(description="HyperionOS build script") - parser.add_argument("target", choices=["build", "build-mini", "build-micro", "build-test", "build-mini-test", "build-micro-test", "clean", "prod", "prod-mini"]) - parser.add_argument("--arch", choices=["cct", "oc"], default=None, - help="Target architecture") - parser.add_argument("--release", dest="release", action="store_true", default=True, - help="Release build: eeprom placed as startup.lua (default)") - parser.add_argument("--dev", dest="release", action="store_false", - help="Dev build: boot.lua and eeprom copied unchanged") - parser.add_argument( - "--makeuser", metavar=("USERNAME", "PASSWORD"), nargs=2, action="append", - default=[], - help=( - "Pre-create a user on first boot (dev builds only). " - "May be specified multiple times. " - "Example: --makeuser root secretpass --makeuser alice alicepass" - ), - ) - - args = parser.parse_args() - - if args.makeuser and args.release: - parser.error("--makeuser is only allowed with --dev builds") - - if args.target == "clean": - clean() - return - - prod = "prod" in args.target - minify = "mini" in args.target or "micro" in args.target - micro = "micro" in args.target - include_test = "test" in args.target - - if micro: - import lz4.block - - run_build(minify=minify, micro=micro, include_test=include_test, arch=args.arch, release=args.release, prod=prod) - - if args.makeuser: - print("Injecting first-boot user setup ...") - inject_makeusers(args.makeuser, args.arch) - print() - - print("Build complete.") - - -if __name__ == "__main__": +#!/usr/bin/env python3 +""" +Usage: + python build.py [--arch cct|oc] [--release|--dev] + +Targets: + build + build-mini + build-micro + build-test + build-mini-test + build-micro-test + clean + prod + prod-mini + +Arch flags: + --arch cct + --arch oc + +Release flags: + --release + --dev +""" + +import sys +import shutil +import argparse +import subprocess +import json +import os +from pathlib import Path +from typing import Union + +PROJECT_ROOT = Path(__file__).resolve().parent +SRC_ROOT = PROJECT_ROOT / "Src" +TEST_ROOT = PROJECT_ROOT / "Test" +BUILD_ROOT = PROJECT_ROOT / "Build" +PROD_ROOT = PROJECT_ROOT / "prod" + +ARCH_BOOT_DIR = { + "cct": Path("boot") / "cct", + "oc": Path("boot") / "oc", +} + + +def clean(): + if BUILD_ROOT.exists(): + print(f"Removing {BUILD_ROOT} ...") + shutil.rmtree(BUILD_ROOT) + else: + print("Nothing to clean.") + +def cleanprod(): + if PROD_ROOT.exists(): + print(f"Removing {PROD_ROOT} ...") + shutil.rmtree(PROD_ROOT) + else: + print("Nothing to clean.") + + +def has_minify_header(path: Path) -> bool: + try: + with path.open("r", encoding="utf-8", errors="ignore") as f: + for _ in range(3): + if "--:Minify:--" in f.readline(): + return True + except OSError: + pass + return False + + +def minify_file(src: Path) -> str: + result = subprocess.run( + ["npm", "exec", "luamin", "--", "-f", str(src)], + capture_output=True, + text=True + ) + if result.returncode != 0: + print(f" ! luamin failed: {result.stderr.strip()}", file=sys.stderr) + sys.exit(1) + return result.stdout + + +def compress_lz4(data: bytes) -> bytes: + return lz4.frame.compress(data) + + +def process_root(src_root: Path, out_root: Path, minify: bool, micro: bool, arch:Union[str, None], prod:bool): + print(f"Building from {src_root}") + print(f"Output to {out_root}") + print() + + for pkg_dir in sorted(src_root.iterdir()): + if not pkg_dir.is_dir(): + continue + + if pkg_dir.name[:18] == "Hyperion-firmware-": + if pkg_dir.name != f"Hyperion-firmware-{arch}": + if prod != True: + continue + + data_dir=pkg_dir / "data" + + if not data_dir.is_dir(): + continue + + print(f"== Package: {pkg_dir.name} ==") + + for src in sorted(data_dir.rglob("*")): + if not src.is_file(): + continue + + rel = src.relative_to(data_dir) + + dst = out_root / rel + if prod: + dst = out_root / pkg_dir.name / rel + + dst.parent.mkdir(parents=True, exist_ok=True) + + print(f" Processing: {src.relative_to(src_root)}") + + if has_minify_header(src): + if minify: + print(" > Minifying") + content = minify_file(src) + if micro: + print(" > LZ4 compressing") + compressed = compress_lz4(content.encode("utf-8")) + dst.write_bytes(compressed) + else: + dst.write_text(content, encoding="utf-8") + else: + print(" > Copying") + shutil.copy2(src, dst) + else: + print(" > Copying") + shutil.copy2(src, dst) + + print() + + +def install_bootloader(arch: str, release: bool): + boot_dir = BUILD_ROOT / "$" / ARCH_BOOT_DIR[arch] + eeprom = boot_dir / "eeprom" + + eeprom_dst_name = "startup.lua" if release else "eeprom" + print(f" Installing: eeprom -> Build/{eeprom_dst_name}") + shutil.copy2(eeprom, BUILD_ROOT / eeprom_dst_name) + + +def run_build(minify: bool, micro: bool, include_test: bool, arch: Union[str, None], release: bool, prod: bool): + clean() + BUILD_ROOT.mkdir() + if prod: + cleanprod() + PROD_ROOT.mkdir() + + out_root = BUILD_ROOT / "$" if arch else BUILD_ROOT + + process_root(SRC_ROOT, out_root, minify, micro, arch, False) + if prod: + process_root(SRC_ROOT, PROD_ROOT, minify, micro, arch, True) + + if include_test: + process_root(TEST_ROOT, out_root, minify, micro) + + if arch: + print("Installing bootloader files ...") + install_bootloader(arch, release) + print() + + +def _make_firstboot_kmod(users): + lines = [] + lines.append("local kernel = ...") + lines.append("local auth = kernel.auth") + lines.append("") + + for username, password in users: + u = username.replace("\\", "\\\\").replace("'", "\\'") + p = password.replace("\\", "\\\\").replace("'", "\\'") + + if username == "root": + lines.append("do") + lines.append(" local ok, err = auth.setPassword(0, '" + p + "')") + lines.append(" if ok then") + lines.append(" kernel.log('FIRSTBOOT: root password set')") + lines.append(" else") + lines.append(" kernel.log('FIRSTBOOT: root password error: ' .. tostring(err), 'ERROR')") + lines.append(" end") + lines.append("end") + else: + lines.append("do") + lines.append(" local uid, err = auth.newUser('" + u + "', '" + p + "')") + lines.append(" if uid then") + lines.append(" kernel.log('FIRSTBOOT: created user " + u + " uid=' .. tostring(uid))") + lines.append(" else") + lines.append(" kernel.log('FIRSTBOOT: failed to create user " + u + ": ' .. tostring(err), 'ERROR')") + lines.append(" end") + lines.append("end") + lines.append("") + + lines.append("do") + lines.append(" local ok, err = pcall(function()") + lines.append(" kernel.vfs.remove('/lib/modules/Hyperion/50_firstboot_users.kmod')") + lines.append(" end)") + lines.append(" if not ok then") + lines.append(" kernel.log('FIRSTBOOT: could not self-delete: ' .. tostring(err), 'WARN')") + lines.append(" end") + lines.append("end") + + return "\n".join(lines) + "\n" + + +def inject_makeusers(users, arch): + base = BUILD_ROOT / "$" if arch else BUILD_ROOT + kmod_path = base / "lib" / "modules" / "Hyperion" / "50_firstboot_users.kmod" + kmod_path.parent.mkdir(parents=True, exist_ok=True) + kmod_path.write_text(_make_firstboot_kmod(users), encoding="utf-8") + print(" Wrote first-boot user setup -> " + str(kmod_path.relative_to(BUILD_ROOT))) + + +def main(): + parser = argparse.ArgumentParser(description="HyperionOS build script") + parser.add_argument("target", choices=["build", "build-mini", "build-micro", "build-test", "build-mini-test", "build-micro-test", "clean", "prod", "prod-mini"]) + parser.add_argument("--arch", choices=["cct", "oc"], default=None, + help="Target architecture") + parser.add_argument("--release", dest="release", action="store_true", default=True, + help="Release build: eeprom placed as startup.lua (default)") + parser.add_argument("--dev", dest="release", action="store_false", + help="Dev build: boot.lua and eeprom copied unchanged") + parser.add_argument( + "--makeuser", metavar=("USERNAME", "PASSWORD"), nargs=2, action="append", + default=[], + help=( + "Pre-create a user on first boot (dev builds only). " + "May be specified multiple times. " + "Example: --makeuser root secretpass --makeuser alice alicepass" + ), + ) + + args = parser.parse_args() + + if args.makeuser and args.release: + parser.error("--makeuser is only allowed with --dev builds") + + if args.target == "clean": + clean() + return + + prod = "prod" in args.target + minify = "mini" in args.target or "micro" in args.target + micro = "micro" in args.target + include_test = "test" in args.target + + if micro: + import lz4.block + + run_build(minify=minify, micro=micro, include_test=include_test, arch=args.arch, release=args.release, prod=prod) + + if args.makeuser: + print("Injecting first-boot user setup ...") + inject_makeusers(args.makeuser, args.arch) + print() + + print("Build complete.") + + +if __name__ == "__main__": main() \ No newline at end of file diff --git a/docs/kernel/boot.cfg.md b/docs/kernel/boot.cfg.md index 83ea6bb..c2ec588 100644 --- a/docs/kernel/boot.cfg.md +++ b/docs/kernel/boot.cfg.md @@ -29,4 +29,7 @@ logTaskExit showModLoad log module loads + +tmpToDisk + writes tmp to disk instead of ram ``` \ No newline at end of file -- 2.55.0 From 49c9e5e37c4f517b7701f9c1c7df9750e26e0d4b Mon Sep 17 00:00:00 2001 From: astronand Date: Thu, 23 Jul 2026 14:33:16 -0400 Subject: [PATCH 4/6] finished http implementation working on spm and liveboot env --- Src/Hyperion-core/authors.txt | 2 + Src/Hyperion-core/data/bin/httptest | 7 + Src/Hyperion-core/data/lib/http | 113 ++++---- Src/Hyperion-core/description.txt | 1 + Src/Hyperion-core/version.txt | 1 + Src/Hyperion-firmware-ac/authors.txt | 3 + Src/Hyperion-firmware-ac/description.txt | 1 + Src/Hyperion-firmware-ac/version.txt | 1 + Src/Hyperion-firmware-ccpc/authors.txt | 2 + Src/Hyperion-firmware-ccpc/description.txt | 1 + Src/Hyperion-firmware-ccpc/version.txt | 1 + Src/Hyperion-firmware-cct/authors.txt | 2 + .../data/lib/modules/cc-tweaked/22_http.kmod | 266 ++++++------------ .../lib/modules/cc-tweaked/30_deamon.kmod | 13 +- Src/Hyperion-firmware-cct/description.txt | 1 + Src/Hyperion-firmware-cct/version.txt | 1 + Src/Hyperion-firmware-oc/authors.txt | 1 + Src/Hyperion-firmware-oc/description.txt | 1 + Src/Hyperion-firmware-oc/version.txt | 1 + Src/Hyperion-kernel/authors.txt | 3 + Src/Hyperion-kernel/data/boot/kernel.lua | 96 +++++++ .../data/lib/modules/hyperion/11_ld.kmod | 76 ++--- .../data/lib/modules/hyperion/12_devfs.kmod | 4 +- .../data/lib/modules/hyperion/20_socket.kmod | 4 +- .../lib/modules/hyperion/45_hypervisor.kmod | 26 +- .../data/lib/modules/hyperion/90_init.kmod | 1 + .../data/lib/modules/hyperion/91_login.kmod | 10 - Src/Hyperion-kernel/description.txt | 1 + Src/Hyperion-kernel/version.txt | 1 + Src/bit32/authors.txt | 2 + Src/bit32/description.txt | 1 + Src/bit32/version.txt | 1 + Src/blake2s/authors.txt | 2 + Src/blake2s/description.txt | 1 + Src/blake2s/version.txt | 1 + Src/coreutils/authors.txt | 3 + Src/coreutils/data/etc/sysinit/autorun/login | 169 +++++++++++ Src/coreutils/description.txt | 1 + Src/coreutils/version.txt | 1 + Src/deflate/authors.txt | 2 + Src/deflate/description.txt | 1 + Src/deflate/version.txt | 1 + Src/gfxterm/authors.txt | 2 + .../data/usr/local/share/fonts/default8x9.psf | Bin 0 -> 3358 bytes Src/gfxterm/description.txt | 1 + Src/gfxterm/version.txt | 1 + Src/hysh/authors.txt | 2 + Src/hysh/description.txt | 1 + Src/hysh/version.txt | 1 + Src/iniparse/authors.txt | 2 + Src/iniparse/description.txt | 1 + Src/iniparse/version.txt | 1 + Src/install.json | 12 - Src/installer/authors.txt | 2 + Src/installer/description.txt | 1 + Src/installer/version.txt | 1 + Src/json/authors.txt | 2 + Src/json/description.txt | 1 + Src/json/version.txt | 1 + Src/lua/authors.txt | 2 + Src/lua/description.txt | 1 + Src/lua/version.txt | 1 + Src/micro/authors.txt | 2 + Src/micro/description.txt | 1 + Src/micro/version.txt | 1 + Src/minify/authors.txt | 3 + Src/minify/description.txt | 1 + Src/minify/version.txt | 1 + Src/pid/authors.txt | 2 + Src/pid/description.txt | 1 + Src/pid/version.txt | 1 + Src/spm/authors.txt | 2 + Src/spm/data/bin/spm | 68 ++++- Src/spm/description.txt | 1 + Src/spm/version.txt | 1 + Src/sysinit/authors.txt | 2 + Src/sysinit/data/usr/lib/sysinit/sysinit | 47 ++-- Src/sysinit/description.txt | 1 + Src/sysinit/version.txt | 1 + Src/xz/authors.txt | 5 + Src/xz/description.txt | 1 + Src/xz/version.txt | 1 + packages/HyperionOS.pkg => bootstrap/vm.lua | 0 compile.py | 196 +++++++++++++ installers/HyperionOS-install-cct.lua | 233 --------------- packages/Hyperion-core.pkg | 12 + packages/Hyperion-firmware-ac.pkg | 13 + packages/Hyperion-firmware-ccpc.pkg | 12 + packages/Hyperion-firmware-cct.pkg | 12 + packages/Hyperion-firmware-oc.pkg | 11 + packages/Hyperion-kernel.pkg | 13 + packages/bit32.pkg | 12 + packages/blake2s.pkg | 12 + packages/coreutils.pkg | 13 + packages/deflate.pkg | 12 + packages/gfxterm.pkg | 12 + packages/hysh.pkg | 12 + packages/iniparse.pkg | 12 + packages/installer.pkg | 12 + packages/json.pkg | 12 + packages/lua.pkg | 12 + packages/micro.pkg | 12 + packages/minify.pkg | 13 + packages/pid.pkg | 12 + packages/raw/Hyperion-core.tar.gz | Bin 0 -> 2885 bytes packages/raw/Hyperion-firmware-ac.tar.gz | Bin 0 -> 3179 bytes packages/raw/Hyperion-firmware-ccpc.tar.gz | Bin 0 -> 8960 bytes packages/raw/Hyperion-firmware-cct.tar.gz | Bin 0 -> 11467 bytes packages/raw/Hyperion-firmware-oc.tar.gz | Bin 0 -> 1026 bytes packages/raw/Hyperion-kernel.tar.gz | Bin 0 -> 34243 bytes packages/raw/bit32.tar.gz | Bin 0 -> 1170 bytes packages/raw/blake2s.tar.gz | Bin 0 -> 1649 bytes packages/raw/coreutils.tar.gz | Bin 0 -> 7735 bytes packages/raw/deflate.tar.gz | Bin 0 -> 29626 bytes packages/raw/gfxterm.tar.gz | Bin 0 -> 2537 bytes packages/raw/hysh.tar.gz | Bin 0 -> 27923 bytes packages/raw/iniparse.tar.gz | Bin 0 -> 842 bytes packages/raw/installer.tar.gz | Bin 0 -> 521 bytes packages/raw/json.tar.gz | Bin 0 -> 3587 bytes packages/raw/lua.tar.gz | Bin 0 -> 2995 bytes packages/raw/micro.tar.gz | Bin 0 -> 3989 bytes packages/raw/minify.tar.gz | Bin 0 -> 16379 bytes packages/raw/pid.tar.gz | Bin 0 -> 1370 bytes packages/raw/spm.tar.gz | Bin 0 -> 1072 bytes packages/raw/sysinit.tar.gz | Bin 0 -> 1335 bytes packages/raw/xz.tar.gz | Bin 0 -> 11353 bytes packages/spm.pkg | 20 +- packages/sysinit.pkg | 12 + packages/xz.pkg | 15 + spm.json | 50 ++-- 130 files changed, 1128 insertions(+), 635 deletions(-) create mode 100644 Src/Hyperion-core/authors.txt create mode 100644 Src/Hyperion-core/data/bin/httptest create mode 100644 Src/Hyperion-core/description.txt create mode 100644 Src/Hyperion-core/version.txt create mode 100644 Src/Hyperion-firmware-ac/authors.txt create mode 100644 Src/Hyperion-firmware-ac/description.txt create mode 100644 Src/Hyperion-firmware-ac/version.txt create mode 100644 Src/Hyperion-firmware-ccpc/authors.txt create mode 100644 Src/Hyperion-firmware-ccpc/description.txt create mode 100644 Src/Hyperion-firmware-ccpc/version.txt create mode 100644 Src/Hyperion-firmware-cct/authors.txt create mode 100644 Src/Hyperion-firmware-cct/description.txt create mode 100644 Src/Hyperion-firmware-cct/version.txt create mode 100644 Src/Hyperion-firmware-oc/authors.txt create mode 100644 Src/Hyperion-firmware-oc/description.txt create mode 100644 Src/Hyperion-firmware-oc/version.txt create mode 100644 Src/Hyperion-kernel/authors.txt delete mode 100644 Src/Hyperion-kernel/data/lib/modules/hyperion/91_login.kmod create mode 100644 Src/Hyperion-kernel/description.txt create mode 100644 Src/Hyperion-kernel/version.txt create mode 100644 Src/bit32/authors.txt create mode 100644 Src/bit32/description.txt create mode 100644 Src/bit32/version.txt create mode 100644 Src/blake2s/authors.txt create mode 100644 Src/blake2s/description.txt create mode 100644 Src/blake2s/version.txt create mode 100644 Src/coreutils/authors.txt create mode 100644 Src/coreutils/data/etc/sysinit/autorun/login create mode 100644 Src/coreutils/description.txt create mode 100644 Src/coreutils/version.txt create mode 100644 Src/deflate/authors.txt create mode 100644 Src/deflate/description.txt create mode 100644 Src/deflate/version.txt create mode 100644 Src/gfxterm/authors.txt create mode 100644 Src/gfxterm/data/usr/local/share/fonts/default8x9.psf create mode 100644 Src/gfxterm/description.txt create mode 100644 Src/gfxterm/version.txt create mode 100644 Src/hysh/authors.txt create mode 100644 Src/hysh/description.txt create mode 100644 Src/hysh/version.txt create mode 100644 Src/iniparse/authors.txt create mode 100644 Src/iniparse/description.txt create mode 100644 Src/iniparse/version.txt delete mode 100644 Src/install.json create mode 100644 Src/installer/authors.txt create mode 100644 Src/installer/description.txt create mode 100644 Src/installer/version.txt create mode 100644 Src/json/authors.txt create mode 100644 Src/json/description.txt create mode 100644 Src/json/version.txt create mode 100644 Src/lua/authors.txt create mode 100644 Src/lua/description.txt create mode 100644 Src/lua/version.txt create mode 100644 Src/micro/authors.txt create mode 100644 Src/micro/description.txt create mode 100644 Src/micro/version.txt create mode 100644 Src/minify/authors.txt create mode 100644 Src/minify/description.txt create mode 100644 Src/minify/version.txt create mode 100644 Src/pid/authors.txt create mode 100644 Src/pid/description.txt create mode 100644 Src/pid/version.txt create mode 100644 Src/spm/authors.txt create mode 100644 Src/spm/description.txt create mode 100644 Src/spm/version.txt create mode 100644 Src/sysinit/authors.txt create mode 100644 Src/sysinit/description.txt create mode 100644 Src/sysinit/version.txt create mode 100644 Src/xz/authors.txt create mode 100644 Src/xz/description.txt create mode 100644 Src/xz/version.txt rename packages/HyperionOS.pkg => bootstrap/vm.lua (100%) create mode 100644 compile.py delete mode 100644 installers/HyperionOS-install-cct.lua create mode 100644 packages/Hyperion-firmware-ac.pkg create mode 100644 packages/Hyperion-firmware-ccpc.pkg create mode 100644 packages/Hyperion-firmware-oc.pkg create mode 100644 packages/bit32.pkg create mode 100644 packages/blake2s.pkg create mode 100644 packages/coreutils.pkg create mode 100644 packages/deflate.pkg create mode 100644 packages/gfxterm.pkg create mode 100644 packages/hysh.pkg create mode 100644 packages/iniparse.pkg create mode 100644 packages/installer.pkg create mode 100644 packages/json.pkg create mode 100644 packages/lua.pkg create mode 100644 packages/micro.pkg create mode 100644 packages/minify.pkg create mode 100644 packages/pid.pkg create mode 100644 packages/raw/Hyperion-core.tar.gz create mode 100644 packages/raw/Hyperion-firmware-ac.tar.gz create mode 100644 packages/raw/Hyperion-firmware-ccpc.tar.gz create mode 100644 packages/raw/Hyperion-firmware-cct.tar.gz create mode 100644 packages/raw/Hyperion-firmware-oc.tar.gz create mode 100644 packages/raw/Hyperion-kernel.tar.gz create mode 100644 packages/raw/bit32.tar.gz create mode 100644 packages/raw/blake2s.tar.gz create mode 100644 packages/raw/coreutils.tar.gz create mode 100644 packages/raw/deflate.tar.gz create mode 100644 packages/raw/gfxterm.tar.gz create mode 100644 packages/raw/hysh.tar.gz create mode 100644 packages/raw/iniparse.tar.gz create mode 100644 packages/raw/installer.tar.gz create mode 100644 packages/raw/json.tar.gz create mode 100644 packages/raw/lua.tar.gz create mode 100644 packages/raw/micro.tar.gz create mode 100644 packages/raw/minify.tar.gz create mode 100644 packages/raw/pid.tar.gz create mode 100644 packages/raw/spm.tar.gz create mode 100644 packages/raw/sysinit.tar.gz create mode 100644 packages/raw/xz.tar.gz create mode 100644 packages/sysinit.pkg create mode 100644 packages/xz.pkg diff --git a/Src/Hyperion-core/authors.txt b/Src/Hyperion-core/authors.txt new file mode 100644 index 0000000..73c23ff --- /dev/null +++ b/Src/Hyperion-core/authors.txt @@ -0,0 +1,2 @@ +Hyperion +Astronand \ No newline at end of file diff --git a/Src/Hyperion-core/data/bin/httptest b/Src/Hyperion-core/data/bin/httptest new file mode 100644 index 0000000..6f220aa --- /dev/null +++ b/Src/Hyperion-core/data/bin/httptest @@ -0,0 +1,7 @@ +local http=require("http") +local ok,err = xpcall(http.get, debug.traceback, "http://localhost:8000/spm.json") +if not ok then + print(err) +else + print(err.body) +end \ No newline at end of file diff --git a/Src/Hyperion-core/data/lib/http b/Src/Hyperion-core/data/lib/http index d313a9a..820e3c5 100644 --- a/Src/Hyperion-core/data/lib/http +++ b/Src/Hyperion-core/data/lib/http @@ -26,8 +26,7 @@ local function parseUrl(url) end local function buildRequest(req) - local host, path = - parseUrl(req.url) + local host, path = parseUrl(req.url) if not host then return nil, path @@ -75,73 +74,39 @@ local function buildRequest(req) return table.concat(out, "\r\n") end -local function parseResponse(raw) - local headerEnd = - raw:find( - "\r\n\r\n", - 1, - true - ) - - if not headerEnd then - return nil, "EBADMSG" +local function parseResponse(response) + local headerBlock, body = response:match("^(.-)\r\n\r\n(.*)$") + if not headerBlock then + return nil, "invalid HTTP response" end - local headerPart = - raw:sub(1, headerEnd - 1) - - local body = - raw:sub(headerEnd + 4) - - local lines = {} - - for line in headerPart:gmatch("[^\r\n]+") do - lines[#lines + 1] = line - end - - local _, code, msg = - lines[1]:match( - "^(HTTP/%S+)%s+(%d+)%s*(.*)$" - ) - local headers = {} - for i = 2, #lines do - local k, v = - lines[i]:match( - "^([^:]+):%s*(.*)$" - ) + -- Parse status line + local statusLine, rest = headerBlock:match("^(.-)\r\n(.*)$") + if not statusLine then + statusLine = headerBlock + rest = "" + end - if k then - headers[k:lower()] = v + local version, code, message = statusLine:match("^(HTTP/%d+%.%d+)%s+(%d+)%s+(.*)$") + + -- Parse headers + for line in (rest .. "\r\n"):gmatch("(.-)\r\n") do + local key, value = line:match("^([^:]+):%s*(.*)$") + if key then + headers[key:lower()] = value end end return { - code = tonumber(code), - message = msg, - headers = headers, - body = body + code=tonumber(code), + message=message, + headers=headers, + body=body } end -local function readAll(fd) - local out = "" - - while true do - local chunk = - syscall.read(fd, 4096) - - if not chunk or chunk == "" then - break - end - - out = out .. chunk - end - - return out -end - function http.request(req) local raw, err = buildRequest(req) @@ -151,34 +116,50 @@ function http.request(req) end local fd = - syscall.socket(0, 0) + syscall.socket() if not fd then return nil, "ESOCKET" end - local ok, err = - syscall.connect(fd, req.url) + local host, path = parseUrl(req.url) + + if not host then + syscall.close(fd) + return nil, path + end + + local proto = req.url:match("^(https?://)") + + local base = proto .. host + + local ok, err = syscall.connect(fd, base) if not ok then syscall.close(fd) return nil, err end - local ok2, err2 = - syscall.write(fd, raw) + local ok2, err2 = syscall.write(fd, raw) if not ok2 then syscall.close(fd) return nil, err2 end - local resp = - readAll(fd) + local out = {} + + while true do + local chunk = syscall.read(fd, 4096) + if chunk == "" then + break + end + + out[#out+1] = chunk + end syscall.close(fd) - - return parseResponse(resp) + return parseResponse(table.concat(out)) end function http.get(url, headers) diff --git a/Src/Hyperion-core/description.txt b/Src/Hyperion-core/description.txt new file mode 100644 index 0000000..ded52f4 --- /dev/null +++ b/Src/Hyperion-core/description.txt @@ -0,0 +1 @@ +Core library for Hyperion \ No newline at end of file diff --git a/Src/Hyperion-core/version.txt b/Src/Hyperion-core/version.txt new file mode 100644 index 0000000..afaf360 --- /dev/null +++ b/Src/Hyperion-core/version.txt @@ -0,0 +1 @@ +1.0.0 \ No newline at end of file diff --git a/Src/Hyperion-firmware-ac/authors.txt b/Src/Hyperion-firmware-ac/authors.txt new file mode 100644 index 0000000..98a48f1 --- /dev/null +++ b/Src/Hyperion-firmware-ac/authors.txt @@ -0,0 +1,3 @@ +Hyperion +Astronand +GHXX (Advanced Computers) \ No newline at end of file diff --git a/Src/Hyperion-firmware-ac/description.txt b/Src/Hyperion-firmware-ac/description.txt new file mode 100644 index 0000000..2ba69f2 --- /dev/null +++ b/Src/Hyperion-firmware-ac/description.txt @@ -0,0 +1 @@ +firmware for Advanced Computers \ No newline at end of file diff --git a/Src/Hyperion-firmware-ac/version.txt b/Src/Hyperion-firmware-ac/version.txt new file mode 100644 index 0000000..afaf360 --- /dev/null +++ b/Src/Hyperion-firmware-ac/version.txt @@ -0,0 +1 @@ +1.0.0 \ No newline at end of file diff --git a/Src/Hyperion-firmware-ccpc/authors.txt b/Src/Hyperion-firmware-ccpc/authors.txt new file mode 100644 index 0000000..73c23ff --- /dev/null +++ b/Src/Hyperion-firmware-ccpc/authors.txt @@ -0,0 +1,2 @@ +Hyperion +Astronand \ No newline at end of file diff --git a/Src/Hyperion-firmware-ccpc/description.txt b/Src/Hyperion-firmware-ccpc/description.txt new file mode 100644 index 0000000..788478d --- /dev/null +++ b/Src/Hyperion-firmware-ccpc/description.txt @@ -0,0 +1 @@ +firmware for CraftOS PC \ No newline at end of file diff --git a/Src/Hyperion-firmware-ccpc/version.txt b/Src/Hyperion-firmware-ccpc/version.txt new file mode 100644 index 0000000..afaf360 --- /dev/null +++ b/Src/Hyperion-firmware-ccpc/version.txt @@ -0,0 +1 @@ +1.0.0 \ No newline at end of file diff --git a/Src/Hyperion-firmware-cct/authors.txt b/Src/Hyperion-firmware-cct/authors.txt new file mode 100644 index 0000000..73c23ff --- /dev/null +++ b/Src/Hyperion-firmware-cct/authors.txt @@ -0,0 +1,2 @@ +Hyperion +Astronand \ No newline at end of file diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod index f35b515..0e1fa0e 100644 --- a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod @@ -9,25 +9,15 @@ kernel.cct.httpqueue = kernel.cct.httpqueue or {} kernel.cct.httpresponse = kernel.cct.httpresponse or {} kernel.cct.httperror = kernel.cct.httperror or {} -local function parseRawRequest(raw) - local sepLen = 4 - - local headerEnd = - raw:find("\r\n\r\n", 1, true) - - if not headerEnd then - headerEnd = - raw:find("\n\n", 1, true) - - sepLen = 2 - end +local function parseRawRequest(raw, address) + local headerEnd = raw:find("\r\n\r\n", 1, true) local headerPart local body = "" if headerEnd then headerPart = raw:sub(1, headerEnd - 1) - body = raw:sub(headerEnd + sepLen) + body = raw:sub(headerEnd + 4) else headerPart = raw end @@ -42,37 +32,25 @@ local function parseRawRequest(raw) return nil, "EINVAL" end - local method, path = - lines[1]:match("^(%S+)%s+(%S+)") - - if not method or not path then - return nil, "EBADMSG" + local split=string.split(lines[1], " ") + if #split~=3 then + return nil, "EINVAL" end + local method, path, ver = table.unpack(split) local headers = {} for i = 2, #lines do - local k, v = - lines[i]:match("^([^:]+):%s*(.*)$") - + local k, v = lines[i]:match("^([^:]+):%s*(.*)$") if k then headers[k] = v end end - local host = headers.Host or headers.host - - if not host and not path:match("^https?://") then - return nil, "EHOSTUNREACH" - end - - local url - - if path:match("^https?://") then - url = path - else - url = "http://" .. host .. path + if path:sub(1,1)~="/" then + return nil, "EINVAL" end + local url = address..path local req = { url = url, @@ -84,7 +62,7 @@ local function parseRawRequest(raw) req.body = body end - return req + return req, url end local function buildResponse(resp) @@ -93,37 +71,19 @@ local function buildResponse(resp) end local code, msg = resp.getResponseCode() - - local headers = - resp:getResponseHeaders() - - local body = - resp:readAll() or "" + local headers = resp.getResponseHeaders() + local body = resp.readAll() or "" + resp.close() local out = { "HTTP/1.1 " .. tostring(code) .. " " .. - tostring(msg) + tostring(msg or "") } - local hasLength = false - - for k, v in pairs(headers or {}) do - if k:lower() == "content-length" then - hasLength = true - end - - out[#out + 1] = - tostring(k) .. - ": " .. - tostring(v) - end - - if not hasLength then - out[#out + 1] = - "Content-Length: " .. - tostring(#body) + for i,v in pairs(headers) do + out[#out+1] = i..": "..v end out[#out + 1] = "" @@ -139,155 +99,91 @@ function handler.connect(fd, address) return nil, "EBADF" end - fdo.socket.rbuf = "" - fdo.socket.closed = false - fdo.socket.httpid = nil - fdo.handle.write = function(raw) - local req, err = - parseRawRequest(raw) + local req, url = parseRawRequest(raw, address) if not req then - return nil, err + return nil, url end - local id = - tostring(kernel.uuid()) - - fdo.socket.httpid = id - - kernel.cct.httpqueue[id] = true - - local ok, err = - http.request(req, id) + kernel.cct.httpqueue[url] = true + local ok, err = http.request(req) if not ok then - kernel.cct.httpqueue[id] = nil + kernel.cct.httpqueue[url] = nil return nil, err end + if fdo.socket.active then + fdo.socket.content=nil + fdo.socket.file.close() + fdo.socket.file=nil + end + fdo.socket.active=true + fdo.socket.url=url return true end fdo.handle.read = function(count) - count = count or 4096 - - local sock = fdo.socket - - if #sock.rbuf > 0 then - local out = - sock.rbuf:sub(1, count) - - sock.rbuf = - sock.rbuf:sub(count + 1) - - return out + if not fdo.socket.active then + return end - local id = sock.httpid - - if not id then - return "" + if not kernel.cct.httpqueue[fdo.socket.url] then + fdo.socket.file=kernel.sfile(buildResponse(kernel.cct.httpresponse[fdo.socket.url])) + kernel.cct.httpqueue[fdo.socket.url]=nil + kernel.cct.httpresponse[fdo.socket.url]=nil end - local function finish(resp) - sock.rbuf = - buildResponse(resp) or "" - - local out = - sock.rbuf:sub(1, count) - - sock.rbuf = - sock.rbuf:sub(count + 1) - - return out - end - - if kernel.cct.httpresponse[id] then - local resp = - kernel.cct.httpresponse[id] - - kernel.cct.httpresponse[id] = nil - kernel.cct.httpqueue[id] = nil - - return finish(resp) - end - - if kernel.cct.httperror[id] then - local err = - kernel.cct.httperror[id] - - kernel.cct.httperror[id] = nil - kernel.cct.httpqueue[id] = nil - - return nil, err - end - - kernel.currentTask.status = "D" - - local coro - - coro = function() - if kernel.cct.httpresponse[id] then - local resp = - kernel.cct.httpresponse[id] - - kernel.cct.httpresponse[id] = nil - kernel.cct.httpqueue[id] = nil - - kernel.asyncReturn( - finish(resp) - ) - - return - end - - if kernel.cct.httperror[id] then - local err = - kernel.cct.httperror[id] - - kernel.cct.httperror[id] = nil - kernel.cct.httpqueue[id] = nil - - kernel.asyncReturn( - nil, - err - ) - - return - end - - coroutine.yield() - end - - kernel.currentTask.ksh = - coroutine.create(function() - local ok, err = - xpcall( - coro, - debug.traceback - ) - - if not ok then - kernel.asyncReturn( - nil, - err - ) + if not fdo.socket.file then + kernel.currentTask.io=function() + if not kernel.cct.httpqueue[fdo.socket.url] then + fdo.socket.file=kernel.sfile(buildResponse(kernel.cct.httpresponse[fdo.socket.url])) + kernel.cct.httpqueue[fdo.socket.url]=nil + kernel.cct.httpresponse[fdo.socket.url]=nil + return fdo.socket.file.read(count) end - end) + end + kernel.currentTask.status="D" + return + else + return fdo.socket.file.read(count) + end + end + + fdo.handle.seek = function(whence, offset) + if not fdo.socket.active then + return + end + + if not kernel.cct.httpqueue[fdo.socket.url] then + fdo.socket.file=kernel.sfile(buildResponse(kernel.cct.httpresponse[fdo.socket.url])) + kernel.cct.httpqueue[fdo.socket.url]=nil + kernel.cct.httpresponse[fdo.socket.url]=nil + end + + if not fdo.socket.file then + kernel.currentTask.io=function() + if not kernel.cct.httpqueue[fdo.socket.url] then + fdo.socket.file=kernel.sfile(buildResponse(kernel.cct.httpresponse[fdo.socket.url])) + kernel.cct.httpqueue[fdo.socket.url]=nil + kernel.cct.httpresponse[fdo.socket.url]=nil + return fdo.socket.file.seek(whence, offset) + end + end + kernel.currentTask.status="D" + return + else + return fdo.socket.file.seek(whence, offset) + end end fdo.handle.close = function() - fdo.socket.closed = true - - local id = - fdo.socket.httpid - - if id then - kernel.cct.httpqueue[id] = nil - kernel.cct.httpresponse[id] = nil - kernel.cct.httperror[id] = nil - end + fdo.socket.file.close() + fdo.socket.active=false + kernel.cct.httpqueue[fdo.socket.url] = nil + kernel.cct.httpresponse[fdo.socket.url] = nil + kernel.cct.httperror[fdo.socket.url] = nil return true end diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_deamon.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_deamon.kmod index 551a274..0892e73 100644 --- a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_deamon.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_deamon.kmod @@ -74,11 +74,16 @@ kernel.processes.cctdeamon = function() kernel.cct.fifo.push("T") end elseif eventType == "http_success" then - kernel.cct.httpqueue[event[2]]=nil - kernel.cct.httpresponse[event[2]]=event[3] + if kernel.cct.httpqueue[event[2]] then + kernel.cct.httpqueue[event[2]]=nil + kernel.cct.httpresponse[event[2]]=event[3] + end elseif eventType == "http_failure" then - kernel.cct.httpqueue[event[2]]=nil - kernel.cct.httperror[event[2]]=event[3] + if kernel.cct.httpqueue[event[2]] then + kernel.cct.httpqueue[event[2]]=nil + kernel.cct.httperror[event[2]]=event[3] + kernel.cct.httpresponse[event[2]]=event[4] + end end timeout = false diff --git a/Src/Hyperion-firmware-cct/description.txt b/Src/Hyperion-firmware-cct/description.txt new file mode 100644 index 0000000..8ed4624 --- /dev/null +++ b/Src/Hyperion-firmware-cct/description.txt @@ -0,0 +1 @@ +firmware for ComputerCraft Tweaked \ No newline at end of file diff --git a/Src/Hyperion-firmware-cct/version.txt b/Src/Hyperion-firmware-cct/version.txt new file mode 100644 index 0000000..589268e --- /dev/null +++ b/Src/Hyperion-firmware-cct/version.txt @@ -0,0 +1 @@ +1.3.0 \ No newline at end of file diff --git a/Src/Hyperion-firmware-oc/authors.txt b/Src/Hyperion-firmware-oc/authors.txt new file mode 100644 index 0000000..4b62d45 --- /dev/null +++ b/Src/Hyperion-firmware-oc/authors.txt @@ -0,0 +1 @@ +Hyperion \ No newline at end of file diff --git a/Src/Hyperion-firmware-oc/description.txt b/Src/Hyperion-firmware-oc/description.txt new file mode 100644 index 0000000..74fbb40 --- /dev/null +++ b/Src/Hyperion-firmware-oc/description.txt @@ -0,0 +1 @@ +firmware for Opencomputers \ No newline at end of file diff --git a/Src/Hyperion-firmware-oc/version.txt b/Src/Hyperion-firmware-oc/version.txt new file mode 100644 index 0000000..6c6aa7c --- /dev/null +++ b/Src/Hyperion-firmware-oc/version.txt @@ -0,0 +1 @@ +0.1.0 \ No newline at end of file diff --git a/Src/Hyperion-kernel/authors.txt b/Src/Hyperion-kernel/authors.txt new file mode 100644 index 0000000..19a2cbd --- /dev/null +++ b/Src/Hyperion-kernel/authors.txt @@ -0,0 +1,3 @@ +Hyperion +Astronand +Spsf \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/boot/kernel.lua b/Src/Hyperion-kernel/data/boot/kernel.lua index d5afe4e..9112e34 100644 --- a/Src/Hyperion-kernel/data/boot/kernel.lua +++ b/Src/Hyperion-kernel/data/boot/kernel.lua @@ -193,6 +193,100 @@ function kernel.newUUID() return uuid end +function kernel.sfile(str, writeable) + local buf = {str or ""} + local pos = 1 + local closed = false + + local function content() + return table.concat(buf) + end + + local function set_content(s) + buf = {s} + end + + local function flush() + str=content() + end + + local file = {} + + function file.read(n) + assert(not closed, "file is closed") + + local s = content() + local len = #s + + if not n then + local out = s:sub(pos) + pos = len + 1 + return out + end + + local out = s:sub(pos, pos + n - 1) + pos = pos + #out + return out + end + + if writeable then + function file.write(data) + assert(not closed, "file is closed") + + local s = content() + local before = s:sub(1, pos - 1) + local after = s:sub(pos + #data) + + set_content(before .. data .. after) + pos = pos + #data + + return true + end + end + + function file.seek(whence, offset) + assert(not closed, "file is closed") + + local s = content() + local len = #s + + whence = whence or "cur" + offset = offset or 0 + + if whence == "set" then + pos = offset + 1 + elseif whence == "cur" then + pos = pos + offset + elseif whence == "end" then + pos = len + offset + 1 + else + error("invalid whence") + end + + if pos < 1 then pos = 1 end + if pos > len + 1 then pos = len + 1 end + + return pos - 1 + end + + function file.close() + assert(not closed, "file is closed") + flush() + closed = true + end + + function file.flush() + assert(not closed, "file is closed") + flush() + end + + function file.content() + return str + end + + return file +end + kernel.syscalls={} local modules={[0]={}} for i=0, 100 do @@ -297,6 +391,7 @@ kernel.syscalls["halt"]=function() end end +kernel.saveLog() kernel.log("Running modules") for _,p in ipairs(modules) do for _,v in ipairs(p) do @@ -310,6 +405,7 @@ for _,p in ipairs(modules) do local status, err = xpcall(func,debug.traceback, kernel) if not status then kernel.panic("ModuRunErr: "..tostring(err)) end if kernel.config.showModLoad then kernel.log("Loaded module "..v, "DBUG", 0x00FFFF) end + if kernel.config.moreLogsaves then kernel.saveLog() end end end diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/11_ld.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/11_ld.kmod index 302edf0..3909e2a 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/11_ld.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/11_ld.kmod @@ -9,55 +9,39 @@ kernel.reqcache = cache local function require(module, ...) if cache[module] then return cache[module].ret end - kernel.currentTask.status = "D" local args = {...} - kernel.currentTask.ksh = coroutine.create(function() - local coro = function() - for _, path in ipairs(kernel.searchpaths) do - local filepath = path:gsub("?", module) - if kernel.vfs.exists(filepath) then - if kernel.vfs.type(filepath) == "directory" then - filepath = filepath .. "/init.lua" - if kernel.vfs.type(filepath) == "directory" then - kernel.asyncReturn(false, "Module not found: "..module) - return - end - end - - local fd = kernel.vfs.open(filepath, "r") - local chunks = {} - while true do - local chunk = kernel.vfs.read(fd, 4096) - if not chunk or chunk == "" then break end - chunks[#chunks + 1] = chunk - coroutine.yield() - end - kernel.vfs.close(fd) - local data = table.concat(chunks) - local func, err = load(data, "@"..module, "t", kernel._U) - if not func then - kernel.asyncReturn(false, "Error loading module "..module..": "..tostring(err)) - return - end - local ok, ret = xpcall(func, debug.traceback, table.unpack(args)) - if not ok then - kernel.asyncReturn(false, "Error running module "..module..": "..tostring(ret)) - return - end - cache[module] = {ret = ret, expires = kernel.EFI:getEpochMs() + 120000} - kernel.asyncReturn(true, ret) - return + for _, path in ipairs(kernel.searchpaths) do + local filepath = path:gsub("?", module) + if kernel.vfs.exists(filepath) then + if kernel.vfs.type(filepath) == "directory" then + filepath = filepath .. "/init.lua" + if kernel.vfs.type(filepath) == "directory" then + error("Module not found: "..module) end - coroutine.yield() end - kernel.asyncReturn(false, "Module not found: "..module) + local fd = kernel.vfs.open(filepath, "r") + local chunks = {} + while true do + local chunk = kernel.vfs.read(fd, 4096) + if not chunk or chunk == "" then break end + chunks[#chunks + 1] = chunk + end + kernel.vfs.close(fd) + local data = table.concat(chunks) + local func, err = load(data, "@"..module, "t", kernel._U) + if not func then + error("Error loading module "..module..": "..tostring(err)) + end + local ok, ret = xpcall(func, debug.traceback, table.unpack(args)) + if not ok then + error("Error running module "..module..": "..tostring(ret)) + end + cache[module] = {ret = ret, expires = kernel.EFI:getEpochMs() + 120000} + return ret end - local status, err = xpcall(coro, debug.traceback) - if not status then - kernel.asyncReturn(false, "Error in require coroutine for module "..module..": "..tostring(err)) - end - end) + coroutine.yield() + end + error("Module not found: "..module) end -kernel.syscalls["require"] = require -_G.require = function(...) return syscall.require(...) end \ No newline at end of file +_G.require = function(...) return require(...) end \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod index 12121f0..0a01ce5 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod @@ -217,7 +217,7 @@ data[".meta"]=strFile(buildMeta({ log="/var/log/syslog.log" })) -if kernel.EFI:getEEPROM() then +if kernel.EFI.getEEPROM then function data.eeprom(op, mode) if op=="type" then return "character device" @@ -255,7 +255,7 @@ if kernel.EFI:getEEPROM() then end end -if kernel.EFI:getNvram() then +if kernel.EFI.getNvram then function data.nvram(op, mode) if op=="type" then return "character device" diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod index cf70b3c..ab31491 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod @@ -22,7 +22,7 @@ local function getHandler(address) end end -function socket.socket(domain, socktype) +function socket.socket() local fd = kernel.vfs.newfd({ handle = {}, @@ -54,7 +54,7 @@ function socket.socket(domain, socktype) local fdo = kernel.currentTask.fd[fd] fdo.handle.read = function() - return "" + return nil, "ENOTCONN" end fdo.handle.write = function() diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod index 0985a6d..12cbe09 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod @@ -396,22 +396,16 @@ function kernel.main() end if task.status == "D" then - if task.ksh then - coroutine.resume(task.ksh) - if coroutine.status(task.ksh) == "dead" then - task.ksh = nil - if task.status == "D" then - task.status = "R" - end - - if kernel.config.debugSyscalls then - kernel.log("Task " .. task.pid .. " IO wait completed", "DBUG", 0x00FFFF) - local sysret = task.syscallReturn - for i = 2, #sysret do - local v = type(sysret[i]) == "table" and table.serialize(sysret[i]) or tostring(sysret[i]) - kernel.log(" retval[" .. (i-1) .. "] = " .. v, "DBUG", 0x00FFFF) - end - end + if task.io then + local ret = {xpcall(task.io, debug.traceback)} + if not ret[1] then + task.syscallReturn = {false, table.unpack(ret, 2)} + task.status = "R" + task.io=nil + elseif #ret>1 then + task.syscallReturn = {true, table.unpack(ret, 2)} + task.status = "R" + task.io=nil end end end diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/90_init.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/90_init.kmod index 1727621..4f623c6 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/90_init.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/90_init.kmod @@ -25,6 +25,7 @@ kernel.tasks["1"] = { else kernel.panic("Init system exited: " .. tostring(err)) end + kernel.saveLog() end), name = "sysinit", diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/91_login.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/91_login.kmod deleted file mode 100644 index f40d92a..0000000 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/91_login.kmod +++ /dev/null @@ -1,10 +0,0 @@ ---:Minify:-- -local kernel = ... -if not kernel.vfs.exists("/root") then kernel.vfs.mkdir("/root") end - -kernel.processes.login = function() - local ok, err = pcall(kernel.hpv.execspawn, "/bin/login", "login") - if not ok then - kernel.log("Failed to exec /bin/login: " .. tostring(err), "ERROR", 0xFF0000) - end -end diff --git a/Src/Hyperion-kernel/description.txt b/Src/Hyperion-kernel/description.txt new file mode 100644 index 0000000..1b2c79c --- /dev/null +++ b/Src/Hyperion-kernel/description.txt @@ -0,0 +1 @@ +Hyperion kernel package \ No newline at end of file diff --git a/Src/Hyperion-kernel/version.txt b/Src/Hyperion-kernel/version.txt new file mode 100644 index 0000000..3e1ad72 --- /dev/null +++ b/Src/Hyperion-kernel/version.txt @@ -0,0 +1 @@ +1.5.0 \ No newline at end of file diff --git a/Src/bit32/authors.txt b/Src/bit32/authors.txt new file mode 100644 index 0000000..5788630 --- /dev/null +++ b/Src/bit32/authors.txt @@ -0,0 +1,2 @@ +Hyperion +Lua \ No newline at end of file diff --git a/Src/bit32/description.txt b/Src/bit32/description.txt new file mode 100644 index 0000000..e507ac3 --- /dev/null +++ b/Src/bit32/description.txt @@ -0,0 +1 @@ +Bit32 package for Hyperion \ No newline at end of file diff --git a/Src/bit32/version.txt b/Src/bit32/version.txt new file mode 100644 index 0000000..afaf360 --- /dev/null +++ b/Src/bit32/version.txt @@ -0,0 +1 @@ +1.0.0 \ No newline at end of file diff --git a/Src/blake2s/authors.txt b/Src/blake2s/authors.txt new file mode 100644 index 0000000..73c23ff --- /dev/null +++ b/Src/blake2s/authors.txt @@ -0,0 +1,2 @@ +Hyperion +Astronand \ No newline at end of file diff --git a/Src/blake2s/description.txt b/Src/blake2s/description.txt new file mode 100644 index 0000000..a290ab9 --- /dev/null +++ b/Src/blake2s/description.txt @@ -0,0 +1 @@ +blake2s package for Hyperion \ No newline at end of file diff --git a/Src/blake2s/version.txt b/Src/blake2s/version.txt new file mode 100644 index 0000000..afaf360 --- /dev/null +++ b/Src/blake2s/version.txt @@ -0,0 +1 @@ +1.0.0 \ No newline at end of file diff --git a/Src/coreutils/authors.txt b/Src/coreutils/authors.txt new file mode 100644 index 0000000..19a2cbd --- /dev/null +++ b/Src/coreutils/authors.txt @@ -0,0 +1,3 @@ +Hyperion +Astronand +Spsf \ No newline at end of file diff --git a/Src/coreutils/data/etc/sysinit/autorun/login b/Src/coreutils/data/etc/sysinit/autorun/login new file mode 100644 index 0000000..51b9c86 --- /dev/null +++ b/Src/coreutils/data/etc/sysinit/autorun/login @@ -0,0 +1,169 @@ +--:Minify:-- +syscall.open("/dev/input/keyboard1", "r") --stdin (fd 0) +syscall.open("/dev/tty/1", "w") --stdout (fd 1) +syscall.open("/dev/null", "w") --stderr (fd 2) + + +local MAX_ATTEMPTS = 3 + +local function readLine(mask) + local input = "" + while true do + local ch = syscall.read(0) + if not ch or ch == "" then + elseif ch == "\n" then + syscall.write(1, "\n") + return input + elseif ch == "\b" then + if #input > 0 then + input = input:sub(1, -2) + syscall.write(1, "\b \b") + end + else + input = input .. ch + syscall.write(1, mask or ch) + end + end +end + +local function firstBoot() + local shadow = "" + local _fd, _fderr = pcall(function() + local fd = syscall.open("/etc/shadow", "r") + shadow = syscall.read(fd, 65535) or "" + syscall.close(fd) + end) + if shadow:match("%S") then return end + + syscall.devctl(1, "clear") + syscall.devctl(1, "spos", 1, 1) + syscall.devctl(1, "sfgc", 0x00FF00) + syscall.write(1, "HyperionOS First Boot Setup\n") + syscall.devctl(1, "sfgc", 0xFFFFFF) + syscall.write(1, "No root password is set. Please create one now.\n\n") + + while true do + syscall.write(1, "New root password: ") + local pw1 = readLine("*") + syscall.write(1, "Confirm password: ") + local pw2 = readLine("*") + + if pw1 ~= pw2 then + syscall.devctl(1, "sfgc", 0xFF0000) + syscall.write(1, "Passwords do not match. Try again.\n\n") + syscall.devctl(1, "sfgc", 0xFFFFFF) + elseif #pw1 < 6 then + syscall.devctl(1, "sfgc", 0xFF0000) + syscall.write(1, "Password too short (minimum 6 characters).\n\n") + syscall.devctl(1, "sfgc", 0xFFFFFF) + else + local ok, err = syscall.setpassword(0, pw1) + if ok then + syscall.devctl(1, "sfgc", 0x00FF00) + syscall.write(1, "Root password set.\n\n") + syscall.devctl(1, "sfgc", 0xFFFFFF) + sleep(0.5) + break + else + syscall.devctl(1, "sfgc", 0xFF0000) + syscall.write(1, "Error: " .. tostring(err) .. "\n") + syscall.devctl(1, "sfgc", 0xFFFFFF) + end + end + end +end + +local function spawnShell(username, uid, shell, homedir) + local existsOk, existsErr = pcall(syscall.exists, shell) + if not existsOk or not existsErr then + syscall.write(1, "login: shell not found: " .. shell .. "\n") + sleep(2) + return false + end + + local accessOk, accessErr = pcall(syscall.access, shell, "rx") + + syscall.setEnviron("HOME", homedir) + syscall.setEnviron("USER", username) + syscall.setEnviron("SHELL", shell) + syscall.setEnviron("PATH", "/bin/") + + local setuidOk, setuidErr = pcall(syscall.setuid, uid) + if not setuidOk then + syscall.write(1, "login: setuid failed: " .. tostring(setuidErr) .. "\n") + sleep(2) + return false + end + + local chdirOk, chdirErr = pcall(syscall.chdir, homedir) + if not chdirOk then + pcall(syscall.chdir, "/") + end + + local ok, err = pcall(syscall.execspawn, shell, username .. ":shell") + if not ok then + syscall.write(1, "login: failed to launch shell: " .. tostring(err) .. "\n") + sleep(2) + return false + end + + syscall.exit(0) +end + +local function doLogin() + syscall.devctl(1, "clear") + syscall.devctl(1, "sfgc", 0xFFFFFF) + syscall.devctl(1, "sbgc", 0x000000) + syscall.devctl(1, "spos", 1, 1) + + local hostname = syscall.getHostname() or "hyperion" + syscall.write(1, "HyperionOS\n") + syscall.write(1, hostname .. " login\n\n") + + local attempts = 0 + while attempts < MAX_ATTEMPTS do + syscall.devctl(1, "sfgc", 0xFFFFFF) + syscall.write(1, "Username: ") + local username = readLine(nil) + + if username ~= "" then + + syscall.write(1, "Password: ") + local password = readLine("*") + local uid = syscall.getuidbyname(username) + + local ok, err = syscall.login(uid, password) + if ok then + local uid = syscall.getuid() + local pwent = syscall.getpasswd(uid) + + local shell = (pwent and pwent.shell) or "/bin/hysh" + local homedir = (pwent and pwent.homedir) or "/" + + syscall.devctl(1, "sfgc", 0x00FF00) + syscall.write(1, "\nWelcome, " .. username .. "!\n") + syscall.devctl(1, "sfgc", 0xFFFFFF) + sleep(0.3) + + spawnShell(username, uid, shell, homedir) + return -- back to login prompt + else + attempts = attempts + 1 + sleep(1) + syscall.devctl(1, "sfgc", 0xFF0000) + syscall.write(1, "Login incorrect.\n\n") + syscall.devctl(1, "sfgc", 0xFFFFFF) + end + end + end + + syscall.devctl(1, "sfgc", 0xFF0000) + syscall.write(1, "Maximum login attempts exceeded.\n") + syscall.devctl(1, "sfgc", 0xFFFFFF) + sleep(5) +end + +firstBoot() +while true do + doLogin() +end diff --git a/Src/coreutils/description.txt b/Src/coreutils/description.txt new file mode 100644 index 0000000..3dee00c --- /dev/null +++ b/Src/coreutils/description.txt @@ -0,0 +1 @@ +core utilities for user management \ No newline at end of file diff --git a/Src/coreutils/version.txt b/Src/coreutils/version.txt new file mode 100644 index 0000000..afaf360 --- /dev/null +++ b/Src/coreutils/version.txt @@ -0,0 +1 @@ +1.0.0 \ No newline at end of file diff --git a/Src/deflate/authors.txt b/Src/deflate/authors.txt new file mode 100644 index 0000000..256705f --- /dev/null +++ b/Src/deflate/authors.txt @@ -0,0 +1,2 @@ +Hyperion +Haoqian He \ No newline at end of file diff --git a/Src/deflate/description.txt b/Src/deflate/description.txt new file mode 100644 index 0000000..c547c28 --- /dev/null +++ b/Src/deflate/description.txt @@ -0,0 +1 @@ +Libdeflate for Hyperion \ No newline at end of file diff --git a/Src/deflate/version.txt b/Src/deflate/version.txt new file mode 100644 index 0000000..9bfe78d --- /dev/null +++ b/Src/deflate/version.txt @@ -0,0 +1 @@ +1.0.0-release \ No newline at end of file diff --git a/Src/gfxterm/authors.txt b/Src/gfxterm/authors.txt new file mode 100644 index 0000000..73c23ff --- /dev/null +++ b/Src/gfxterm/authors.txt @@ -0,0 +1,2 @@ +Hyperion +Astronand \ No newline at end of file diff --git a/Src/gfxterm/data/usr/local/share/fonts/default8x9.psf b/Src/gfxterm/data/usr/local/share/fonts/default8x9.psf new file mode 100644 index 0000000000000000000000000000000000000000..a383fa251f6179b360bc01ae5840c044e20bd1f9 GIT binary patch literal 3358 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 then - sel=sel-1 - end - elseif key==keys.enter then - m[sel].func() - elseif key==keys.tab then - desc(m[sel].desc) - elseif key==keys.backspace then - exit=true - end - end -end - -local releases,page={},1 -while true do - local raw=download("https://git.astronand.dev/api/v1/repos/Hyperion/HyperionOS/releases?page="..tostring(page).."&limit=1") - if raw=="[]\n" then - break - end - releases[page]=json.decode(raw)[1] - page=page+1 -end - -local function makePage(start, num) - local m={} - for i=start, num do - if not releases[i] then break end - local release=releases[i] - m[#m+1]={ - name=release.name, - desc=release.body, - color=release.prerelease and colors.orange or colors.white, - func=function() - term.clear() - term.setCursorPos(1,1) - local data=download("https://git.astronand.dev/Hyperion/HyperionOS/raw/tag/"..release.tag_name.."/Src/install.json") - if not data then - term.clear() - term.setCursorPos(1,1) - print("Unable to find package list for ver "..release.tag_name..":\n"..err) - sleep(3) - return - end - releasename=release.tag_name - packagelist=json.decode(data) - exitall=true - end - } - end - if #releases>start+num then - m[#m+1]={ - name="Next", - desc="Next menu", - color=colors.cyan, - func=function() - local menudata=makePage(start+num, num) - menu(menudata) - end - } - end - return m -end - -printTitle() -menu(makePage(1,5)) -if not exitall then error("Exited") end -term.clear() -term.setCursorPos(1,1) -term.setTextColor(colors.white) -term.write("Formating disk in ") -for i=5, 1, -1 do - term.write(tostring(i)) - sleep(.25) - for v=1, 3 do - term.write(".") - sleep(.25) - end -end -print("") - -local function delDir(dir) - printc(colors.gray, "[ ", colors.green, " LSDIR ", colors.gray, " ] ", colors.white, dir) - local list=fs.list(dir) - printc(colors.gray, "[ ", colors.red, " DELET ", colors.gray, " ] ", colors.white, dir) - for i=1, #list do - if fs.isDir(dir..list[i]) then - if dir..list[i] ~= "/rom" then - delDir(dir..list[i].."/") - fs.delete(dir..list[i]) - end - else - fs.delete(dir..list[i]) - printc(colors.gray, "[ ", colors.red, " DELET ", colors.gray, " ] ", colors.white, dir..list[i]) - end - sleep(.01) - end - sleep(.15) -end - -delDir("/") - -print("") -printc(colors.cyan, " \\\\Installing//") -print("") -printc(colors.white, "Getting package list...") - -local function installdir(path, dir, pkg) - local data=json.decode(download("https://git.astronand.dev/api/v1/repos/Hyperion/HyperionOS/contents/prod/"..pkg..dir.."?ref="..releasename)) - if not data then error("Uh Oh: JSON decode error...") end - for i=1, #data do - local entry=data[i] - if entry.type == "dir" then - installdir(path, dir..entry.name.."/", pkg) - elseif entry.type == "file" then - writeFile(path..dir..entry.name, download(entry.download_url)) - else - error("Uh Oh: unknown entrytype "..entry.path) - end - sleep(.01) - end - sleep(.15) -end - -local function installpkg(pkg) - installdir("/$", "/", pkg) -end - -for i=1, #packagelist do - installpkg(packagelist[i]) -end - -installpkg("Hyperion-firmware-cct") -fs.copy("/$/boot/cct/eeprom", "/startup.lua") - -printc(colors.white, "Rebooting...") -sleep(1) -os.reboot() \ No newline at end of file diff --git a/packages/Hyperion-core.pkg b/packages/Hyperion-core.pkg index e69de29..6936838 100644 --- a/packages/Hyperion-core.pkg +++ b/packages/Hyperion-core.pkg @@ -0,0 +1,12 @@ +{ + "id": "Hyperion-core", + "description": "Core library for Hyperion", + "authors": [ + "Hyperion", + "Astronand" + ], + "dependencies": [], + "version": "1.0.0", + "hash": "e83a8dc42a871c1e16cd56c214cf0ca4bb0079432dc8bd198abbe11d6cf31d4e", + "tarball": "http://localhost:8000/packages/raw/Hyperion-core.tar.xz" +} diff --git a/packages/Hyperion-firmware-ac.pkg b/packages/Hyperion-firmware-ac.pkg new file mode 100644 index 0000000..e03bae2 --- /dev/null +++ b/packages/Hyperion-firmware-ac.pkg @@ -0,0 +1,13 @@ +{ + "id": "Hyperion-firmware-ac", + "description": "firmware for Advanced Computers", + "authors": [ + "Hyperion", + "Astronand", + "GHXX (Advanced Computers)" + ], + "dependencies": [], + "version": "1.0.0", + "hash": "f64be830fc02394eeb9c049a528ed47b97430c6682a577c789d16303dcaad6fc", + "tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-ac.tar.xz" +} diff --git a/packages/Hyperion-firmware-ccpc.pkg b/packages/Hyperion-firmware-ccpc.pkg new file mode 100644 index 0000000..8c3402a --- /dev/null +++ b/packages/Hyperion-firmware-ccpc.pkg @@ -0,0 +1,12 @@ +{ + "id": "Hyperion-firmware-ccpc", + "description": "firmware for CraftOS PC", + "authors": [ + "Hyperion", + "Astronand" + ], + "dependencies": [], + "version": "1.0.0", + "hash": "f3f030d6f6faa137f9950f0ce4ccc598a9b29c729380c100c920fad5aa254076", + "tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-ccpc.tar.xz" +} diff --git a/packages/Hyperion-firmware-cct.pkg b/packages/Hyperion-firmware-cct.pkg index e69de29..cbb3640 100644 --- a/packages/Hyperion-firmware-cct.pkg +++ b/packages/Hyperion-firmware-cct.pkg @@ -0,0 +1,12 @@ +{ + "id": "Hyperion-firmware-cct", + "description": "firmware for ComputerCraft Tweaked", + "authors": [ + "Hyperion", + "Astronand" + ], + "dependencies": [], + "version": "1.3.0", + "hash": "dd69c26ba6f46acb99d6f839474fc50283524bd99df7f67a5d300a749af86dde", + "tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-cct.tar.xz" +} diff --git a/packages/Hyperion-firmware-oc.pkg b/packages/Hyperion-firmware-oc.pkg new file mode 100644 index 0000000..2fafce2 --- /dev/null +++ b/packages/Hyperion-firmware-oc.pkg @@ -0,0 +1,11 @@ +{ + "id": "Hyperion-firmware-oc", + "description": "firmware for Opencomputers", + "authors": [ + "Hyperion" + ], + "dependencies": [], + "version": "0.1.0", + "hash": "8b1bbff272dd07f0e5023c90007ec8d3a84f5b29a59449a75894319c86ee10cd", + "tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-oc.tar.xz" +} diff --git a/packages/Hyperion-kernel.pkg b/packages/Hyperion-kernel.pkg index e69de29..8a5e571 100644 --- a/packages/Hyperion-kernel.pkg +++ b/packages/Hyperion-kernel.pkg @@ -0,0 +1,13 @@ +{ + "id": "Hyperion-kernel", + "description": "Hyperion kernel package", + "authors": [ + "Hyperion", + "Astronand", + "Spsf" + ], + "dependencies": [], + "version": "1.5.0", + "hash": "a17552597f1a4e661804bcf23d26e19664cb6f75cb3058357603df59b033155a", + "tarball": "http://localhost:8000/packages/raw/Hyperion-kernel.tar.xz" +} diff --git a/packages/bit32.pkg b/packages/bit32.pkg new file mode 100644 index 0000000..781736f --- /dev/null +++ b/packages/bit32.pkg @@ -0,0 +1,12 @@ +{ + "id": "bit32", + "description": "Bit32 package for Hyperion", + "authors": [ + "Hyperion", + "Lua" + ], + "dependencies": [], + "version": "1.0.0", + "hash": "9bc32da8ab97f899e85faeb47064433ef4a167e45924c0e583d30f901551bdf5", + "tarball": "http://localhost:8000/packages/raw/bit32.tar.xz" +} diff --git a/packages/blake2s.pkg b/packages/blake2s.pkg new file mode 100644 index 0000000..a085084 --- /dev/null +++ b/packages/blake2s.pkg @@ -0,0 +1,12 @@ +{ + "id": "blake2s", + "description": "blake2s package for Hyperion", + "authors": [ + "Hyperion", + "Astronand" + ], + "dependencies": [], + "version": "1.0.0", + "hash": "c32e2bbeba5d8609f720bce59fad0505d490ee22a6e54b4d830a524e609ac415", + "tarball": "http://localhost:8000/packages/raw/blake2s.tar.xz" +} diff --git a/packages/coreutils.pkg b/packages/coreutils.pkg new file mode 100644 index 0000000..7a48f19 --- /dev/null +++ b/packages/coreutils.pkg @@ -0,0 +1,13 @@ +{ + "id": "coreutils", + "description": "core utilities for user management", + "authors": [ + "Hyperion", + "Astronand", + "Spsf" + ], + "dependencies": [], + "version": "1.0.0", + "hash": "c52244c7fd2ca96780ed684327ebb55872757a4f6c8d90e18367ec4e0d8f10ad", + "tarball": "http://localhost:8000/packages/raw/coreutils.tar.xz" +} diff --git a/packages/deflate.pkg b/packages/deflate.pkg new file mode 100644 index 0000000..1b2b954 --- /dev/null +++ b/packages/deflate.pkg @@ -0,0 +1,12 @@ +{ + "id": "deflate", + "description": "Libdeflate for Hyperion", + "authors": [ + "Hyperion", + "Haoqian He" + ], + "dependencies": [], + "version": "1.0.0-release", + "hash": "43a3df0e6da39aa97c0ee0ce4217e9acffadba4178d03dae5c66bf4627147644", + "tarball": "http://localhost:8000/packages/raw/deflate.tar.xz" +} diff --git a/packages/gfxterm.pkg b/packages/gfxterm.pkg new file mode 100644 index 0000000..b9370a7 --- /dev/null +++ b/packages/gfxterm.pkg @@ -0,0 +1,12 @@ +{ + "id": "gfxterm", + "description": "package providing kernel support for framebuffers and graphics", + "authors": [ + "Hyperion", + "Astronand" + ], + "dependencies": [], + "version": "1.0.0", + "hash": "88eb9f9bb7bb86fb7752601c67e4ab62e88fb7562057a83c101aaf7ffc3ccdc0", + "tarball": "http://localhost:8000/packages/raw/gfxterm.tar.xz" +} diff --git a/packages/hysh.pkg b/packages/hysh.pkg new file mode 100644 index 0000000..ecf2170 --- /dev/null +++ b/packages/hysh.pkg @@ -0,0 +1,12 @@ +{ + "id": "hysh", + "description": "Official Hyperion shell package", + "authors": [ + "Hyperion", + "Spsf" + ], + "dependencies": [], + "version": "1.3.0", + "hash": "d0baaeb889eeaa38a9f100c4954b8f30c36c220ba73d8b8fa878e0fcaeaadb15", + "tarball": "http://localhost:8000/packages/raw/hysh.tar.xz" +} diff --git a/packages/iniparse.pkg b/packages/iniparse.pkg new file mode 100644 index 0000000..e8af038 --- /dev/null +++ b/packages/iniparse.pkg @@ -0,0 +1,12 @@ +{ + "id": "iniparse", + "description": "ini parser", + "authors": [ + "Hyperion", + "Astronand" + ], + "dependencies": [], + "version": "1.0.0", + "hash": "f26f900027066dc2f498a4ccb8306f48c93210e7869b11f4aef9900f2e00e066", + "tarball": "http://localhost:8000/packages/raw/iniparse.tar.xz" +} diff --git a/packages/installer.pkg b/packages/installer.pkg new file mode 100644 index 0000000..3e0ce3c --- /dev/null +++ b/packages/installer.pkg @@ -0,0 +1,12 @@ +{ + "id": "installer", + "description": "Hyperion os live installer", + "authors": [ + "Hyperion", + "Astronand" + ], + "dependencies": [], + "version": "1.0.0", + "hash": "8623a44260062d0066aecc683b45c2ea9e6f438fd74cef050e7bcac7daa33a4f", + "tarball": "http://localhost:8000/packages/raw/installer.tar.xz" +} diff --git a/packages/json.pkg b/packages/json.pkg new file mode 100644 index 0000000..4655b87 --- /dev/null +++ b/packages/json.pkg @@ -0,0 +1,12 @@ +{ + "id": "json", + "description": "JSON library for Hyperion", + "authors": [ + "Hyperion", + "rxi" + ], + "dependencies": [], + "version": "1.0.0", + "hash": "8344035d687f5cafb8c918d6bddd2ba5a7d6c2025aa43def84b942a614583282", + "tarball": "http://localhost:8000/packages/raw/json.tar.xz" +} diff --git a/packages/lua.pkg b/packages/lua.pkg new file mode 100644 index 0000000..1a0dd6d --- /dev/null +++ b/packages/lua.pkg @@ -0,0 +1,12 @@ +{ + "id": "lua", + "description": "Interactive lua shell", + "authors": [ + "Hyperion", + "Spsf" + ], + "dependencies": [], + "version": "1.2.0", + "hash": "69978317dbe981a50aa3194ed68d35bbd4d1e87ba03191aa7b3574712861e54c", + "tarball": "http://localhost:8000/packages/raw/lua.tar.xz" +} diff --git a/packages/micro.pkg b/packages/micro.pkg new file mode 100644 index 0000000..e7b67cf --- /dev/null +++ b/packages/micro.pkg @@ -0,0 +1,12 @@ +{ + "id": "micro", + "description": "micro text editor", + "authors": [ + "Hyperion", + "Spsf" + ], + "dependencies": [], + "version": "1.0.0", + "hash": "20619f7885c20cef538842ad1a958dd5dfbd9a3542997acd7de91f89e57e32db", + "tarball": "http://localhost:8000/packages/raw/micro.tar.xz" +} diff --git a/packages/minify.pkg b/packages/minify.pkg new file mode 100644 index 0000000..7c1c9b4 --- /dev/null +++ b/packages/minify.pkg @@ -0,0 +1,13 @@ +{ + "id": "minify", + "description": "lua minifier", + "authors": [ + "Hyperion", + "Mark Langen", + "Astronand (added goto support)" + ], + "dependencies": [], + "version": "1.0.0", + "hash": "bbbc1c2137b76aec328bf8cc0d246f852af35943175fbcd8e1bf55fc9348e4ba", + "tarball": "http://localhost:8000/packages/raw/minify.tar.xz" +} diff --git a/packages/pid.pkg b/packages/pid.pkg new file mode 100644 index 0000000..1309634 --- /dev/null +++ b/packages/pid.pkg @@ -0,0 +1,12 @@ +{ + "id": "pid", + "description": "Proportional Integral Derivative library", + "authors": [ + "Hyperion", + "Astronand" + ], + "dependencies": [], + "version": "1.0.0", + "hash": "b1941d2a2699774ab94886d866198219608544f63bee6cf2f059d5b1ed9c86e8", + "tarball": "http://localhost:8000/packages/raw/pid.tar.xz" +} diff --git a/packages/raw/Hyperion-core.tar.gz b/packages/raw/Hyperion-core.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..8f353f4885ce562d91b555878804f6bf1929e7ec GIT binary patch literal 2885 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 literal 0 HcmV?d00001 diff --git a/packages/raw/Hyperion-firmware-ac.tar.gz b/packages/raw/Hyperion-firmware-ac.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..e56edb5f10ce44df6e1f27b36a37f239b27adc38 GIT binary patch literal 3179 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 literal 0 HcmV?d00001 diff --git a/packages/raw/Hyperion-firmware-ccpc.tar.gz b/packages/raw/Hyperion-firmware-ccpc.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..699a5f74b732358b50c1d43504109495a0cbb5a5 GIT binary patch literal 8960 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 literal 0 HcmV?d00001 diff --git a/packages/raw/Hyperion-firmware-oc.tar.gz b/packages/raw/Hyperion-firmware-oc.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..307ae1253813c274d61dfd05e0942edb02a3ebc7 GIT binary patch literal 1026 zcmb2|=HO_FNXlaR?@?KhT9lcer<;~plv|!yl&YJbtXGm)#PBxSv46IO#Mzng2MgV1 z3EfVZW2x{~F3h<4W@K)7^~zNz7}XQKbFR(s2@CySoy+lZLW$K{wbU!0_HsY@C@J&! z{oeD9ESD30ot|G)u3e$_<;iY_tra=l0TQ*h%5B_OCU@?i&C{^UDCYKQ|6`m+pUu_o zcd%@ZbUAF`vYFxXghZ>)Y7O({w*Q~*^xSJ-)U&GM^II#HUV2%6qTX%g?IgF0hu&Y2#kh>;VW)rlnff@%wJOtZDi`|8{&y5?_}Bce{?h*rmqdZH9K8Z;f8|&I z`+RH7)OAdojh~;{`BDm`Pb^33S2FW{b%OW>z3WB-u7jwQC`@-llOm_ZMf?# zG*f(EB==1h)6J*not3>QH{)mT?;PgaKUIwV|KwP5f0e&dzu_M{Pw;=vz^tv6dH?EP z{+0Lgf3@FWS-^kZ#uD92<@;ZSKAy4Gd9{-F)n#jXFL-W$d^W#{`KQ7buaKvGH)W4k zosL>|%uoG3tG4D6&UdEz`W4eM14F0(jyk<{tLmw!)Nd?rpWb?4`*UZ-)*si!?AMhP z%+Z#A7M{Cfwc;(K_euBv1$bI);l015{hnH^xc;+nM}Zi*L$hXi&xrEge|>38-c{?1 zUo+}Y)&+;B+T1Byo~ifdRsXsljQ`m|@Q=s8`KRybtbYE7>C2bj`yWpHznh8SPyLSj z_0#e^`A#ytuK(~~@OS;^|Nc!(E$JUklOOzF{Ix!Csg?d+t(P+Y8LKY+cP{$zU;XF_ z+yCi;Hvc7A?&ju;T`6BW;jY&HraKJ(+5gMW{Qua3r`aN@XMq4HdG6o(sb1~!nVr=DX013Skh1`ucne5hRaL186B00RR6yP_Zz literal 0 HcmV?d00001 diff --git a/packages/raw/Hyperion-kernel.tar.gz b/packages/raw/Hyperion-kernel.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..96b6b704f5320753db70a9328a3c33aedc84fded GIT binary patch literal 34243 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 z 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 literal 0 HcmV?d00001 diff --git a/packages/raw/blake2s.tar.gz b/packages/raw/blake2s.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..71927c86d0c843a98541e86708409060d79aca16 GIT binary patch literal 1649 zcmb2|=HO_FNXlaRpOllBooZC9SCUx7@HRR+|CWcyIph6FE}@*a4$fSiyXbA!WV1}| z+^ti?UU^TS%42bqYx^xVrqG}7tIzf1<}LJG+ER9S4!g~~pXXBbp3gRvcz?tC-{WMH zdU5x^7PeI)iD6~2l9P)fk5!#xdG4N4w}pLXYUPxs--{262u=u`*YhachGXh9COg}k z&*}uO^v$uUeaW|YbwtYX{+G;?tu9Edx4Dq>HR`F&btje})>Fs-OmAX$cX@C8f3c3g z`s0i{_ZxSw{#&ngPygWmtl9rtAOGL`p?=4)|6Up|S59Cznv%zCq42Li?PtQIv^cx- z@~Z!9mzI6rFTnagTTyfl>&~zO6_uR%KkFC#`JZRldpX5u-CVn~|11lC@4x;3{r3N- zx8?oT`5?kyDxtCczx;)N_xnG+*eJ*J{`a5dtnJNC3_sUfe82m7{^R=N|Lr^f*Ggs` z|KEP>|KTOoe>{HvZ~pWC_oN^|h>tN%!_X z)H!s!f3t~N{W+yYwvL@5Yx5>eK3TD2fy!*(<&#a$p9tO4@jFEzwK?U_(lBYis*4jC z{J1`KE%|soa?-KhT`O0ZpH7qT@Y*$5#O~Q-k%nb=wO{4l+;U4Pf$OZuotS4+c+PGO z(pmj>Zmv%9&kxt7g}Z-*cWruCWcKdq$rPVUp7YF}P3f6!$~5WNPaWCh6yEGh+ot~e zz?ZXi!K%pa<9{#R`R$+ZfA+=$&;Ds<&;MQLu&}1=8T<0*3y*E8c{@M;ghRs5kk#GX zy8f997h76iSK4u4+c(K4E)x5W8SUqII{Vv8$!TA2T2}vU+n#N{^!EPy`~Mb1RsK7s zvAoG^)rw_yycr(1r#P!Fj|tGz44?8^`t>L2dj<_s6ON_Lmr`JsULe#U7};p~z-RWc zFlP7DU0#nnn*~Fgn0HLf@Rr&ylgN~C%PM7s{Imz#HcB!aIMTdK^wq3@nh#uVs|;G! zvdnoIn(>P(&){0n=Gdb;8@8>Pe$9?~4S!Z{0f+4)(TH1i$|8FtTDC2GB=GY_c39Kj zLmASgDhtls;E?9r-Z$;>nI7#_na@fAGWy09Wl1;A7Wu87`g2>MuP2N5tVwdJ6T~)r z6Dykie8o zFY{)-lrpwWcB|1}bhO_^#LmOvU{qXK^Uc{k%QEMr_A>HlY>5qQQej$?w>RpC>9b3{ zD|fJjc|DlsoUp{6@iS+Y>;qQWHwPS!C_cJZuhr;!CMKy=Q2$Ot{cFpeCW#Yj1p0kl z8?Udfxa-KYL*s~6*s1ng+^sC`PMUS^v3bxs@NSa7~`ZK3& zm70%*&jqt(DtsQ_W|mvIdX`w7HBE7JnQ(MjY?#N^PLnkW9VfQD=6ad0G&NP|U35x- z;$dGE_xF38wrQ)R-)>}MJsZ*Ra$!li8fNZr71w z-qlmTG;lpBKXgrVk%dQMnuzQ-8>aRUi^ydN5d=OuOsm#Ob$Of4XAAa-BEkCL6EmPr1~x_uaecnenr9 zD|fz0<;!yqwEN(8a>qk$X_FVKZOh-i*xwm>aL3|HYkRmiv->6V*5>y{3)JcDW{lui z9aw+vkmVOv@%xt!p3)TA^5&Gj|5E-R0pGl9|3Cis|KsI-|2gxj|A)8T+WW6M;{N|5 zk@~*Nc5Jl!VSS){-+%3^$A0hM$1&yizx4jk{>uX2YyA?Mox7$+{YL8X%i`aE_y7Kz zp8B6%YMR`2BLSNd_6Fu#|JOe@sqWePKkm2v<){DcP1BG5ub*-I|98bZ$#TV+4~}#S ZtNYEdD0~EA*ku0X|5(3d215V?0|4|@P7444 literal 0 HcmV?d00001 diff --git a/packages/raw/coreutils.tar.gz b/packages/raw/coreutils.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..cdea3977e134ce2f68f91b98bc7707c3268376a0 GIT binary patch literal 7735 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 literal 0 HcmV?d00001 diff --git a/packages/raw/gfxterm.tar.gz b/packages/raw/gfxterm.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..44132d5be943f90b8bd05a9df86484100c010284 GIT binary patch literal 2537 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 literal 0 HcmV?d00001 diff --git a/packages/raw/iniparse.tar.gz b/packages/raw/iniparse.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..1e8f9e05d017c4af1daee796d6f3b1d03635b9bc GIT binary patch literal 842 zcmb2|=HO_FNXlaRpP83gkXTfls#lU&#PD`jZ2m0+k+z-Z)^E6>=D3~3dSh}z*Ot3) z(=NT!oN8pCs%4>J7<+Nc-)}eh7*8F4v1HQ9vz2-U8~XPb-+L^ur|O90qgXRMpFvxDP(kQhtPR~!2!bAp#M z?x_=+sq;ujd@lF5#5uE!(}E63-t#rL^PlnlbAzBv(cAxwhqp9FO#LVST+2IE=eYWt zb5r*R*j%W;@PF;U;Q4HFZ-v}AU(~PtVjs6EbJo*&RRPmK{GV{?@~`*5m;U?Bcs0sF z;(8=U_{;yMSO4p;Zapz6#A<&0^FIyK1^&NG{PSJ$U%1f!-M4?pe~HjPa%ZvK!5M}Y z3|BP&^(Tv#>plPPU->Wj*}l!^>!&2Kov&Z;f5HF%-v2YVv;T^>{ySgwzV-Bv|LZT; zyG1bk;)lSH)&En^eg5@7zV83!>ksGsYrmuZ;di{~j=cY??|nSE>iw>BI94(rv9XD{hQ2R7Z_Y=lzn-Dr(}DRT+>FojQbm6{c1}CqH+!<(E86N&m{njk{U9rtZM@MbRX?un24fguRt5-aY-TGa9+q^mJDr<_^f+c32 z7q+fi<7de=d){tgzVKUmFHSPbMqY1}ySL%Z`;4WFyLVl`_0#Ri4a@1^Zl2f+yDMA|E~J(1hzS)5C4R({yhJLd*mjAsPA{)H=N)1 zUv>8P{VfS;=jwY7{=UEJoBT~_1?Kn_$^!ot|Ghs_?^OF}<`U_mj{l`y|Gz7p)))9a sU*v!38U080OKmvb{@>5k@qem=&6~smW(F*vLHxY@=VtY33;_%b0Bi-d3IG5A literal 0 HcmV?d00001 diff --git a/packages/raw/installer.tar.gz b/packages/raw/installer.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..5899892a6f7a95f624de8d3a4d90becd0dabf334 GIT binary patch literal 521 zcmb2|=HO_JNXlaRpP5%&l9-c|TBKK!Sj6yl){p|Gj{G z{(qU~`66x4inPhxNB{S~u8;q_{*Qa|U;eN5fBt)a-7mH1U;owrv%RPH{@?t^|Juan z|AGGx|5tqdzyELj%eEe7hKWD-=g7}~we$1T|E=d4WWMhIx9$J?KP5lx8E*gmUvh8R z=B&tNyTzF{3NoMgf8u}j&-pd))vr0{ZTu%5{x5!-Z}rbR^-=$i&;FC&bNSobKk^U% a#0z+MC*>~)yQ3m)jsL!zH}7D;J>B>JD)P?y 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 PRL@{s^vs!|f`I`55H9fw literal 0 HcmV?d00001 diff --git a/packages/raw/lua.tar.gz b/packages/raw/lua.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..8b334956fc12660311e75846d808c6dd8a392bc3 GIT binary patch literal 2995 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 YL^J{xIN)d0d;XArazELGp@M+{01H$300000 literal 0 HcmV?d00001 diff --git a/packages/raw/micro.tar.gz b/packages/raw/micro.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..dea88e164dc6beae747936acec9836c5357f70b1 GIT binary patch literal 3989 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 literal 0 HcmV?d00001 diff --git a/packages/raw/minify.tar.gz b/packages/raw/minify.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..90fe30d15b14a3e29581fdfef410f3b460b607a0 GIT binary patch literal 16379 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 Jg<%3C0|4f}q8tDK literal 0 HcmV?d00001 diff --git a/packages/raw/pid.tar.gz b/packages/raw/pid.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..bd5b355e19d0485559771086ca119386d735cb31 GIT binary patch literal 1370 zcmb2|=HO_JNXlaRUyzxiSCUx7@HQ$p|F#>?xAgyA&Gt7}u6=Q}s5$M%2HqD9rP>=3 zxyd>6T`c==Y<-#^bH31QTlS58k7vCr zY5MX<^Xb8-8{aE--}-J-xuxcONPq6x=y|-E&m-d^|8IM}M*WC&>fg&c;+{T_A2i%c z{`6l{@;~RF^7bG3%KzrG{5O~Sw>zM+?RCD{zNZPy7Q%m)yZ%!YoH_CR=fzk5-zw#Q zyg%3cN4~Y*nWkyG<8})t&D-?vyvYCf`^$YksLZSTZgai8<*)qj|CfL5|9q)>r&;ac zt-0Bc^EdpT@A;oU!>|9Rz>h1>?ayyZ2>7t@pX~9kAAjhiY{!snxjUQMaL_VxP zk>7Wf`Jdgt-P4{b{!@m)xjg?LwhM}Vk@)(*^?QBx_2};(?ic&Y-~T_iDQxv>bDL+o zf3LopWyL#LmzQ%1<4!gH`OA#t@9lkDc;MTChWOrN>pHeu`X_DT&75-XeMZCv)y@L} zAua_@-#?`osyftM=iqSZpR(&o=;_n;8+KfotP&B|v18)Y95ME_Gf%BadNzBSdDgN? znQ2*pl|Ms_erqp^Jm&JxTkx*IMID`Gg4yDe?=N2?q;ukVwo$kD)tT=Yg_Q(9OSZh} zI@6IjMeRwUo6-r3qQe}jU#E7v%jCpPzAd=f{`vNolkOD#;GU-9xm06yPR2g(wKsFE zq=gGLA1z+w(8VM$b<-`IH+99+IA%&N-OzQ%taG8!p$VK9PDRLVl=<*PE#-5&nap<0 z69*Rd9aL@B=9yVk@Oc{Jv`a0=E6cMNr#AAZEuSe;8TDks(XOo1(km|h4d{JmZMxz7 zJ#ML2-$dSZtV#=hShh;>!0~<~b%%>GQ5SXw{p4L7sTgtO6vq*pD@XTF>*Lq|EgQ9S z)&ES*&CBkcvD&(eSNhrYsR;s4E2m0Ga+kL~t2`cNdwnYVyw{J;70H+yG`0I=*VTh+&ER!%gc26jYW@Lpu(w&`P=U zSZkI2=Z@y%{f|C8H#(=9^s;Yj__}Yf+^u&lYi=R?3SymNB7zRq;RVw#b81>t!-n3-(p52sH_5T6?!h zB2U(to$-3%=YkX6B5J{A{ZdvGwq%EDSOQirj^1bN*uuxPOHvrZ)V^+d+RFaXVJ;u@Mf_LK^m@K8z&B1{XItHp>CF%HMEV~* zoOl1?ockNasuEvX{nFZb?U>{4ymb~EUu|t?-N~~3Skpw4j{6LETX)S6*S!-v;omIj zJG%q!%qZKtr#JL#@y*p=Q`hf#t!MEfYp!v8R?6bt%S^Yta$6jmyUzH@pG^&49rs*0 z79%YocF3&LpHFIQ7FTXht>UmUd2Z6M?ws|lgy6XF<8F5UZ1z8|XWsw+*!%tL_y7NV zZMyHD_5APkI=8vv?Dok$l|JCU|NrMR_rBN5&3W*9fAEFqiAy>sMDy#ef7$+|J?|Cw z&)x-(N?ArWy`ZS7{B~q?vrx-)nETt|Cfb-ufP6vZt2gz h`}^10zhv{7H}|S;-aPYd zMq-(W&VlZYF`i3Krd--zt9si)&B2?0LvF=>=0oqDFHQbZcb@IBpxocO!}4|<^SG{B zbN-QPkGju)<8-;Yx}EBlcDbtb15wiJ-h9}5n#K3RsT6HPwZcP(6g-657GLn!=-ey! z;H>lX)fZPDFYuIYUzqJF^Xu-mvz0pA}Mm;Id2@PB^m|Hr!j(oH%F9fS`#E%@*KuzsHz_ev8p{%0vaI{u%}&-~|p`k%jlX~0aKJ@)s~Y8vJ*{CD{C{r(Ss#ADj8Pn1t~%Y4B8;ZM2d zSNo@J^FJwmxbb}d1flB10=NJ0H_bToS^k6lhyVYN{@=#>Z@w8&t&6h@!;h2re)lQvAY=9@+8~jHf1OY z-|Bt1>sWE3)vuf|&5t3=m}(`JU;RFz;}WPTJH;S7bb;jgtt(mFy*%Vl}~=Vc$(E;ClX z6m@4}eN^|>=vV63y{{)GzBgMl=gP79;*ok;H}jLfc)y)`%52`P^tDB=gEaH!zFl(F zd~fL4^|Sq~S6}gYf9;#W%{a|=-M2fUWb#ihkc-oMt-4uF|M;O_Jlk{Lb`RatL(_T0n(c+&=B@K(S9mJ^L5`V&y3>_cHZL_6N8B|95};JASGx=ivzl|Ngi9uyK{Zi#Gr1HF_83 z@7d7Xv}cEi!{7E__gDUJ32cg;?DFCN`K4F>S1yeO9;J3nu}Ik9sqH%J;;O4Q zXR^ZI{$o@tjPmD9$(ihFI_v*FGsXM9m%TXWYJRu5!uaRx-sc6mT<;#KgQr7O#=TXHt(Q7Y&TgN@dC6T^SFJ|i$ls2(hpsOk8}!s3 zVp`5x@jam5E5+&ixtndJuVw_zW;6V1etGJ7_9+uAmM|_p@?-zT11nlH=KhxznVA1G|6l*pUTMk$?jlEhC$>NL75@2i)z0^B{Teg>=>JF&*=O}m)BgB7 ztrliXWz1FF@Ap4n<9~hKoFdInXMTRMJI?+?_>29W>;D

=*mnfBl!d)Xns|9%ZLR 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 Date: Tue, 28 Jul 2026 20:13:50 -0400 Subject: [PATCH 5/6] update --- .vscode/settings.json | 3 +- README.md | 10 +- Src/Hyperion-core/data/bin/httptest | 7 - Src/Hyperion-core/data/lib/fs | 13 +- .../data/boot/cct/boot.lua | 7 +- .../data/lib/modules/cc-tweaked/25_tty.kmod | 6 +- Src/Hyperion-kernel/data/boot/kernel.lua | 6 +- .../data/lib/modules/hyperion/01_stdlib.kmod | 1 + .../data/lib/modules/hyperion/10_vfs.kmod | 6 +- .../data/lib/modules/hyperion/20_socket.kmod | 5 + .../lib/modules/hyperion/70_stdlibadv.kmod | 21 + Src/deflate/data/lib/LibDeflate | 4 +- Src/hysh/data/bin/hysh | 6 +- Src/minify/data/lib/{minify.lua => minify} | 0 Src/pid/data/lib/{pid.lua => pid} | 0 Src/spm/data/bin/spm | 358 +++++++++++++++--- Src/spm/dependencies.txt | 4 + Src/tar/authors.txt | 2 + Src/tar/data/bin/tar | 0 Src/tar/data/lib/tar | 201 ++++++++++ Src/tar/description.txt | 0 Src/tar/version.txt | 0 compile.py | 3 +- manifest.lua | 9 +- packages/Hyperion-core.pkg | 2 +- packages/Hyperion-firmware-ac.pkg | 2 +- packages/Hyperion-firmware-ccpc.pkg | 2 +- packages/Hyperion-firmware-cct.pkg | 2 +- packages/Hyperion-firmware-oc.pkg | 2 +- packages/Hyperion-kernel.pkg | 2 +- packages/bit32.pkg | 2 +- packages/blake2s.pkg | 2 +- packages/coreutils.pkg | 2 +- packages/deflate.pkg | 2 +- packages/gfxterm.pkg | 2 +- packages/hysh.pkg | 2 +- packages/iniparse.pkg | 2 +- packages/installer.pkg | 2 +- packages/json.pkg | 2 +- packages/lua.pkg | 2 +- packages/micro.pkg | 2 +- packages/minify.pkg | 2 +- packages/pid.pkg | 2 +- packages/raw/Hyperion-core.tar.gz | Bin 2885 -> 2726 bytes packages/raw/Hyperion-firmware-ac.tar.gz | Bin 3179 -> 3179 bytes packages/raw/Hyperion-firmware-ccpc.tar.gz | Bin 8960 -> 8960 bytes packages/raw/Hyperion-firmware-cct.tar.gz | Bin 11467 -> 11536 bytes packages/raw/Hyperion-firmware-oc.tar.gz | Bin 1026 -> 1026 bytes packages/raw/Hyperion-kernel.tar.gz | Bin 34243 -> 34453 bytes packages/raw/bit32.tar.gz | Bin 1170 -> 1170 bytes packages/raw/blake2s.tar.gz | Bin 1649 -> 1649 bytes packages/raw/coreutils.tar.gz | Bin 7735 -> 7735 bytes packages/raw/deflate.tar.gz | Bin 29626 -> 29691 bytes packages/raw/gfxterm.tar.gz | Bin 2537 -> 2537 bytes packages/raw/hysh.tar.gz | Bin 27923 -> 27951 bytes packages/raw/iniparse.tar.gz | Bin 842 -> 842 bytes packages/raw/installer.tar.gz | Bin 521 -> 521 bytes packages/raw/json.tar.gz | Bin 3587 -> 3587 bytes packages/raw/lua.tar.gz | Bin 2995 -> 2995 bytes packages/raw/micro.tar.gz | Bin 3989 -> 3989 bytes packages/raw/minify.tar.gz | Bin 16379 -> 16398 bytes packages/raw/pid.tar.gz | Bin 1370 -> 1387 bytes packages/raw/spm.tar.gz | Bin 1072 -> 2956 bytes packages/raw/sysinit.tar.gz | Bin 1335 -> 1335 bytes packages/raw/tar.tar.gz | Bin 0 -> 1795 bytes packages/raw/xz.tar.gz | Bin 11353 -> 11353 bytes packages/spm.pkg | 8 +- packages/sysinit.pkg | 2 +- packages/tar.pkg | 12 + packages/xz.pkg | 2 +- spm.json | 7 +- 71 files changed, 638 insertions(+), 103 deletions(-) delete mode 100644 Src/Hyperion-core/data/bin/httptest rename Src/minify/data/lib/{minify.lua => minify} (100%) rename Src/pid/data/lib/{pid.lua => pid} (100%) create mode 100644 Src/spm/dependencies.txt create mode 100644 Src/tar/authors.txt create mode 100644 Src/tar/data/bin/tar create mode 100644 Src/tar/data/lib/tar create mode 100644 Src/tar/description.txt create mode 100644 Src/tar/version.txt create mode 100644 packages/raw/tar.tar.gz create mode 100644 packages/tar.pkg diff --git a/.vscode/settings.json b/.vscode/settings.json index 138447a..1c1fd9a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,6 +6,7 @@ "printf", "printInline", "toHex", - "loadcstr" + "loadcstr", + "userinput" ] } \ No newline at end of file diff --git a/README.md b/README.md index f4f2e14..c1074bc 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,10 @@ See `building.md`. - Functionality is split into kernel modules (`.kmod`) - Task-based lightweight thread/task preemptive scheduler with process isolation and IPC support -- Virtual filesystem unified interface for disk, RAM, and virtual filesystems +- Virtual filesystem - TTY & Shell +- Sockets +- --- @@ -48,6 +50,12 @@ Add your name to `contributors.md` when your PR is merged. --- +## Information + +Trello: https://trello.com/b/8dryrlMi + +--- + ## License This project is licensed under the MIT License. See the LICENSE file for details. diff --git a/Src/Hyperion-core/data/bin/httptest b/Src/Hyperion-core/data/bin/httptest deleted file mode 100644 index 6f220aa..0000000 --- a/Src/Hyperion-core/data/bin/httptest +++ /dev/null @@ -1,7 +0,0 @@ -local http=require("http") -local ok,err = xpcall(http.get, debug.traceback, "http://localhost:8000/spm.json") -if not ok then - print(err) -else - print(err.body) -end \ No newline at end of file diff --git a/Src/Hyperion-core/data/lib/fs b/Src/Hyperion-core/data/lib/fs index e4fcbf8..23e49e8 100644 --- a/Src/Hyperion-core/data/lib/fs +++ b/Src/Hyperion-core/data/lib/fs @@ -1,11 +1,6 @@ --:Minify:-- local fs={} --- "open" : open --- "read" : read --- "write" : write --- "close" : close - function fs.open(path, mode) local fd=syscall.open(path,mode) local ret={ @@ -140,4 +135,12 @@ function fs.isDir(path) return syscall.type(path) == "directory" end +function fs.symlink(target, path) + return syscall.syslink(target, path) +end + +function fs.readlink(path) + return syscall.readlink(path) +end + return fs \ No newline at end of file diff --git a/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua b/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua index 6d9ff92..2ac417b 100644 --- a/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua +++ b/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua @@ -463,7 +463,12 @@ local ok, err = xpcall(function() getTextColor = function() return fg end, - enable=function() end, + enable=function() + for i=1, #allscreens do + allscreens[i].clear() + allscreens[i].setCursorPos(1, 1) + end + end, disable=function() end }, architecture="cct", diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod index f560b6e..58cbe04 100644 --- a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod @@ -220,9 +220,6 @@ local function newtty(obj, id, ev) gbgc=function() return bg end, - gctrl=function() - return serializeBool(kernel.cct.ctrl)..";"..serializeBool(kernel.cct.alt) - end, isvirt=function() return false end, @@ -269,6 +266,9 @@ kernel.devfs.data["input"]["keyboard1"] = function(op, mode) return rv end, write=function(content) + end, + gctrl=function() + return serializeBool(kernel.cct.ctrl)..";"..serializeBool(kernel.cct.alt) end } if mode=="rw" then diff --git a/Src/Hyperion-kernel/data/boot/kernel.lua b/Src/Hyperion-kernel/data/boot/kernel.lua index 9112e34..de11879 100644 --- a/Src/Hyperion-kernel/data/boot/kernel.lua +++ b/Src/Hyperion-kernel/data/boot/kernel.lua @@ -7,10 +7,10 @@ local disks=EFI.disks local arch=EFI.architecture local kernel = {} kernel.LOG_Text="" -kernel.version="HyperionOS V1.2.4-dev_5" -kernel.tag="1.2.4-dev_5" +kernel.version="HyperionOS V1.2.4" +kernel.tag="1.2.4" kernel.process = "Kernel" -kernel.users={[0]="root",[1]="User"} +kernel.users={[0]="root",[1000]="User"} kernel.hostname = "hyperion" kernel.groups = {} kernel.uid = 0 diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod index b4ec413..d6c50d5 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod @@ -23,6 +23,7 @@ function string.split(str, delim, maxResultCountOrNil) assert(#delim == 1, "only delim len 1 supported for now") if not str then return false end maxResultCountOrNil = (maxResultCountOrNil or 0) - 1 + if str == "" then return {} end local rv = {} local buf = "" for i = 1, #str do diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod index 800cd89..decbf4e 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod @@ -124,7 +124,7 @@ end local function validateComponent(comp) local lower = comp:lower() - if not lower:match(SAFE_COMPONENT_PATTERN) then + if not comp:match(SAFE_COMPONENT_PATTERN) then error("EINVAL: illegal characters in path component: " .. comp, 3) end if lower == ".meta" then @@ -276,7 +276,7 @@ local function namei(path, noFollow, symDepth) else validateComponent(comp) - local lname = comp:lower() + local lname = comp local curPath = "/" .. table.concat(stack, "/") @@ -374,7 +374,7 @@ local function normalizePath(path) table.remove(stack) end else - table.insert(stack, comp:lower()) + table.insert(stack, comp) end end diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod index ab31491..ab96543 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/20_socket.kmod @@ -184,11 +184,16 @@ function socket.sockshutdown(fd) return true end +function socket.socketendpoints() + return table.keys(socket.handlers) +end + sys.socket = socket.socket sys.connect = socket.connect sys.listen = socket.listen sys.send = socket.send sys.recv = socket.recv sys.sockshutdown = socket.sockshutdown +sys.socketendpoints = socket.socketendpoints kernel.log("Loaded socket module") \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/70_stdlibadv.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/70_stdlibadv.kmod index 6f768bc..8e0679e 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/70_stdlibadv.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/70_stdlibadv.kmod @@ -19,4 +19,25 @@ function printInline(...) for i = 1, #args do output = output .. tostring(args[i]) .. "\t" end output = output:sub(1, -2) syscall.write(1, output) +end + +function userinput(fd, helpstr, replacestr, fdo) + local str = "" + if helpstr then print(helpstr) end + while true do + local inp = syscall.read(fd) + if inp~="" and inp~=nil then + if inp~="\n" then + if replacestr then + syscall.write(fdo, replacestr) + else + syscall.write(fdo, inp) + end + str = inp + else + break + end + end + end + return str end \ No newline at end of file diff --git a/Src/deflate/data/lib/LibDeflate b/Src/deflate/data/lib/LibDeflate index 8597521..87cd3d9 100644 --- a/Src/deflate/data/lib/LibDeflate +++ b/Src/deflate/data/lib/LibDeflate @@ -315,7 +315,9 @@ end -- CRC-16/CRC-32 computation local band, bnot, xor, lshift, rshift - +local bit32 +local ok, temp = pcall(require, "bit32") +if ok then bit32=temp end if bit ~= nil then band = bit.band bnot = bit.bnot diff --git a/Src/hysh/data/bin/hysh b/Src/hysh/data/bin/hysh index e18c487..9afded8 100644 --- a/Src/hysh/data/bin/hysh +++ b/Src/hysh/data/bin/hysh @@ -1211,9 +1211,9 @@ local function runCommand(command) local proc = syscall.spawn(function() -- Open standard fds so programs that don't do it themselves work correctly. - syscall.open("/dev/input/keyboard1", "r") -- fd 0 stdin - syscall.open("/dev/tty/1", "w") -- fd 1 stdout - syscall.open("/dev/null", "w") -- fd 2 stderr + syscall.open("/proc/self/parent/fd/0", "r") -- fd 0 stdin + syscall.open("/proc/self/parent/fd/1", "w") -- fd 1 stdout + syscall.open("/proc/self/parent/fd/2", "w") -- fd 2 stderr -- exec replaces this coroutine's code with a fresh isolated environment -- compiled from disk by the kernel (via loadExecutable -> freshUserEnv), -- so the child cannot share any upvalue or syscall table state with hysh. diff --git a/Src/minify/data/lib/minify.lua b/Src/minify/data/lib/minify similarity index 100% rename from Src/minify/data/lib/minify.lua rename to Src/minify/data/lib/minify diff --git a/Src/pid/data/lib/pid.lua b/Src/pid/data/lib/pid similarity index 100% rename from Src/pid/data/lib/pid.lua rename to Src/pid/data/lib/pid diff --git a/Src/spm/data/bin/spm b/Src/spm/data/bin/spm index cd87d0c..1845e60 100644 --- a/Src/spm/data/bin/spm +++ b/Src/spm/data/bin/spm @@ -1,68 +1,330 @@ -local args={...} +--:Minify:-- +local spm = function(...) + if syscall.geteuid()~=0 then print("Permission denied") return end + local inpArgs = { ... } + local args = {} + local cloptions = { + S = false, + y = false, + u = false, + R = false, + h = false, + r = false, + Q = false, + l = false, + o = false, + i = false, + e = false, + t = false, + sysroot = "", + init = false, + help = false, + source = false + } --- local test repo -local rootRepo="http://localhost:8000/spm.json" ---local rootRepo="https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm.json" + local i = 1 + local fs = require("fs") + local http = require("http") + local json = require("json") + local tar = require("tar") + local deflate = require("deflate") + local httpcache = {} -local json = require("json") -local http = require("http") -local deflate = require("deflate") - -local function checkRepo(repo) - local resp = http.get(repo) - if resp.code ~= 200 then - return false + local function get(url) + if httpcache[url] then return httpcache[url] end + local ret = http.get(url) + httpcache[url] = ret + return ret end - local repojson = json.decode(resp.body) - if not repojson then - return false + + while i <= #inpArgs do + local v = inpArgs[i] + + if v:sub(1, 2) == "--" then + local opt, value = v:match("^%-%-(.-)=(.*)$") + + if not opt then + opt = v:sub(3) + end + + if cloptions[opt] == nil then + print("spm: unrecognized option '" .. v .. "'.") + print("try 'spm --help' for more information.") + return + end + + if type(cloptions[opt]) == "boolean" then + cloptions[opt] = true + else + if value == nil then + i = i + 1 + value = inpArgs[i] + end + + if value == nil then + print("spm: option '--" .. opt .. "' requires an argument.") + return + end + + cloptions[opt] = value + end + + elseif v:sub(1, 1) == "-" then + for j = 2, #v do + local opt = v:sub(j, j) + + if cloptions[opt] == nil then + print("spm: invalid option '-" .. opt .. "'.") + print("try 'spm --help' for more information.") + return + end + + if type(cloptions[opt]) ~= "boolean" then + print("spm: option '-" .. opt .. "' requires the long form '--" .. opt .. "=value'.") + return + end + + cloptions[opt] = true + end + + else + table.insert(args, v) + end + + i = i + 1 end - return true, repojson -end -local function getRepos(root) - local repos = {} - local visited = {} + if cloptions.sysroot=="" then + syscall.chdir("/") + else + syscall.chdir(cloptions.sysroot) + end - local queue = {root} - local head = 1 + if cloptions.init then + fs.mkdir("var/spm/cache/") + fs.mkdir("var/spm/db/") + fs.writeAllText("var/spm/db/repos.list","") + fs.mkdir("var/spm/db/installed/") + fs.mkdir("etc/spm/") + fs.writeAllText("etc/spm/sources.list","https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm.json\nhttp://localhost:8000/spm.json") + end - while head <= #queue do - local url = queue[head] - head = head + 1 + if not fs.exists("var/spm/") or not fs.exists("etc/spm/") then + print("spm not initialized run \"spm --init\"") + return + end - if not visited[url] then - visited[url] = true + local repodb = string.split(fs.readAllText("var/spm/db/repos.list"), "\n") + local sourcelist = string.split(fs.readAllText("etc/spm/sources.list"), "\n") + local pkgdblist = fs.list("var/spm/db/installed/") + local pkgdb = {} - local ok, repo = checkRepo(url) - if ok then - table.insert(repos, { - url = url, - data = repo - }) + for _,v in ipairs(pkgdblist) do + local file = fs.readAllText("var/spm/db/installed/"..v) + pkgdb[v] = json.decode(file) + end - if repo.refs then - for _, ref in ipairs(repo.refs) do - if not visited[ref] then - queue[#queue + 1] = ref + local function printpkgs(list) + local colWidth=0 + local tmp = syscall.devctl(1, "size") + local sizeX, sizeY = tonumber(tmp:sub(1, tmp:find(";")-1)), tonumber(tmp:sub(tmp:find(";")+1)) + for _, v in ipairs(list) do + if #v + 2 > colWidth then colWidth = #v + 2 end + end + local numCols = math.max(1, math.floor(sizeX / colWidth)) + + for i, v in ipairs(list) do + printInline(v.id) + printInline((" "):rep(colWidth - #v)) + if i % numCols == 0 then print("") end + end + if #list % numCols ~= 0 then print("") end + end + + local function checkRepo(repo) + local resp = get(repo) + if not resp then return false end + if resp.code ~= 200 then + return false + end + local repojson = json.decode(resp.body) + if not repojson then + return false + end + return true, repojson + end + + local function getRepos(root) + local repos = {} + local visited = {} + + local queue = table.values(root) + local head = 1 + + while head <= #queue do + local url = queue[head] + head = head + 1 + + if not visited[url] then + visited[url] = true + + print("GET:"..tostring(head-1).." "..url) + + local ok, repo = checkRepo(url) + if ok then + table.insert(repos, url) + + if repo.refs then + for _, ref in ipairs(repo.refs) do + if not visited[ref] then + queue[#queue + 1] = ref + end end end end end end + + return repos end - return repos -end + local function getPkg(name) + for _, url in ipairs(repodb) do + local ok, repo = checkRepo(url) + if not ok then + print("Failed to contact repository:") + print(url) + print("Consider running 'spm -Sy' to remove broken repositories.") + else + if repo.packages then + if repo.packages[name] then + local pkgurl = repo.packages[name] + local resp = get(pkgurl) + if not resp then + print("Repository: "..url) + print("Has broken package: "..name) + print("Ignoring") + else + if resp.code ~= 200 then + print("Repository: "..url) + print("Has broken package: "..name) + print("Ignoring") + else + local pkgjson = json.decode(resp.body) + if not pkgjson then + print("Repository: "..url) + print("Has broken package: "..name) + print("Ignoring") + else + return { + url=pkgurl, + tar=pkgjson.tarball, + hash=pkgjson.hash, + id=pkgjson.id, + deps=pkgjson.dependencies, + desc=pkgjson.description, + auth=pkgjson.authors, + ver=pkgjson.version + } + end + end + end + end + end + end + end + return false, "target not found: "..name + end -local function getPkg(name) - -end + if cloptions.S then + if cloptions.y then + print("Updating repositories...") + repodb={} + for _,v in ipairs(getRepos(sourcelist)) do + repodb[#repodb+1]=v + end + print("Writing new data...") + local str = "" + for _,v in ipairs(repodb) do + str=str..v.."\n" + end + fs.writeAllText("var/spm/db/repos.list", str) + end + if cloptions.i then + -- info remote + end + local needed = {} + local found = {} + for i,v in ipairs(args) do + local pkg, err = getPkg(v) + if not pkg then print(err) syscall.exit(1) end + needed[#needed+1] = pkg + found[v]=true + end + if cloptions.u then + for i,v in ipairs(table.keys(pkgdb)) do + local pkg, err = getPkg(v) + if pkg then + needed[#needed+1] = pkg + found[v]=true + end + end + end + local head = 0 + while head<#needed do + head=head+1 + for i,v in ipairs(needed[head].deps) do + if not found[v] and not pkgdb[v] then + local pkg, err = getPkg(v) + if pkg then + needed[#needed+1] = pkg + found[v]=true + end + end + end + end + if #needed==0 then + syscall.exit() + end + print("") + print("Packages("..tostring(#needed).."):") + printpkgs(needed) + print("") + while true do + local text = userinput(0, "Proceed with download [Y/n]", nil, 1) + if text=="" then + break + elseif text:lower()=="y" then + break + elseif text:lower()=="n" then + syscall.exit() + end + end -if args[1] == "install" then - local pkg=getPkg(args[2]) -elseif args[1] == "sync" then - error("not implemented") -elseif args[1] == "remove" then - error("not implemented") + local files = {} + for _,v in ipairs(needed) do + local file = http.get(v.tar) + + end + + elseif cloptions.R then + -- remove tree + elseif cloptions.Q then + if cloptions.l then + -- list installed files + elseif cloptions.o then + -- get package file arg[1] is from + elseif cloptions.e then + -- list installed manually + elseif cloptions.i then + -- list installed info + elseif cloptions.t then + -- list orphans + end + end +end +local ok,err = xpcall(spm, debug.traceback, ...) +if not ok then + print("Fatal error in spm:") + print(err) end \ No newline at end of file diff --git a/Src/spm/dependencies.txt b/Src/spm/dependencies.txt new file mode 100644 index 0000000..10ca011 --- /dev/null +++ b/Src/spm/dependencies.txt @@ -0,0 +1,4 @@ +tar +deflate +json +minify \ No newline at end of file diff --git a/Src/tar/authors.txt b/Src/tar/authors.txt new file mode 100644 index 0000000..73c23ff --- /dev/null +++ b/Src/tar/authors.txt @@ -0,0 +1,2 @@ +Hyperion +Astronand \ No newline at end of file diff --git a/Src/tar/data/bin/tar b/Src/tar/data/bin/tar new file mode 100644 index 0000000..e69de29 diff --git a/Src/tar/data/lib/tar b/Src/tar/data/lib/tar new file mode 100644 index 0000000..2876a2a --- /dev/null +++ b/Src/tar/data/lib/tar @@ -0,0 +1,201 @@ +local LibDeflate = require("LibDeflate") +local tar = {} + +local function pad512(n) + return math.ceil(n / 512) * 512 +end + +local function octal(n, size) + local s = string.format("%0" .. (size - 1) .. "o", n) + return s .. "\0" +end + +local function header(name, size, typeflag, link) + local h = string.rep("\0", 512) + + local function put(pos, len, value) + h = h:sub(1, pos - 1) .. + value .. + h:sub(pos + len) + end + + put(1, 100, name) + put(101, 8, octal(0, 8)) + put(109, 8, octal(0, 8)) + put(117, 8, octal(0, 8)) + put(125, 12, octal(size, 12)) + put(137, 12, octal(os.time(), 12)) + put(149, 8, " ") + put(157, 1, typeflag) + + if link then + put(158, 100, link) + end + + put(257, 6, "ustar\0") + put(263, 2, "00") + + local sum = 0 + for i = 1, 512 do + sum = sum + h:byte(i) + end + + put(149, 8, string.format("%06o\0 ", sum)) + + return h +end + +local function add(out, node, prefix) + local path = prefix and (prefix .. "/" .. node.name) + or node.name + + if node.type == "dir" then + table.insert(out, header(path .. "/", 0, "5")) + + for _, child in ipairs(node.content) do + add(out, child, path) + end + + elseif node.type == "file" then + local data = node.content or "" + + table.insert(out, header(path, #data, "0")) + table.insert(out, data) + + local padding = pad512(#data) - #data + if padding > 0 then + table.insert(out, string.rep("\0", padding)) + end + + elseif node.type == "symlink" then + table.insert(out, + header(path, 0, "2", node.content) + ) + end +end + +function tar.pack(tree, gzip) + local out = {} + + add(out, tree) + + table.insert(out, string.rep("\0", 1024)) + + local data = table.concat(out) + + if gzip then + return LibDeflate:CompressGzip(data) + end + + return data +end + +local function read_octal(s) + s = s:gsub("\0.*", "") + return tonumber(s, 8) or 0 +end + +function tar.unpack(data) + if data:sub(1,2) == "\31\139" then + data = assert(LibDeflate:DecompressGzip(data)) + end + + local root = { + type = "dir", + name = "", + content = {} + } + + local function add_path(parts, node) + local current = root + + for i = 1, #parts - 1 do + local name = parts[i] + local found + + for _, child in ipairs(current.content) do + if child.name == name and child.type == "dir" then + found = child + break + end + end + + if not found then + found = { + type = "dir", + name = name, + content = {} + } + table.insert(current.content, found) + end + + current = found + end + + table.insert(current.content, node) + end + + local pos = 1 + + while pos + 511 <= #data do + local h = data:sub(pos, pos + 511) + + if h == string.rep("\0", 512) then + break + end + + local name = h:sub(1,100):gsub("\0.*", "") + local size = read_octal(h:sub(125,136)) + local kind = h:sub(157,157) + + local skip = false + + -- Ignore PAX headers and GNU long filename records + if kind == "x" or kind == "g" or kind == "L" then + skip = true + end + + if not skip then + local node + + if kind == "5" then + node = { + type = "dir", + name = name:gsub("/$", ""), + content = {} + } + + elseif kind == "2" then + node = { + type = "symlink", + name = name, + content = + h:sub(158,257):gsub("\0.*", "") + } + + else + node = { + type = "file", + name = name, + content = + data:sub(pos + 512, + pos + 511 + size) + } + end + + local parts = {} + + for part in node.name:gmatch("[^/]+") do + table.insert(parts, part) + end + + add_path(parts, node) + end + + pos = pos + 512 + pad512(size) + end + + return root +end + +return tar diff --git a/Src/tar/description.txt b/Src/tar/description.txt new file mode 100644 index 0000000..e69de29 diff --git a/Src/tar/version.txt b/Src/tar/version.txt new file mode 100644 index 0000000..e69de29 diff --git a/compile.py b/compile.py index 6431318..8287e38 100644 --- a/compile.py +++ b/compile.py @@ -122,7 +122,7 @@ def create_package(folder): DEFAULT_VERSION, ), "hash": package_hash, - "tarball": f"{API_ROOT}/packages/raw/{name}.tar.xz", + "tarball": f"{API_ROOT}/packages/raw/{name}.tar.gz", } with open(pkg_file, "w", encoding="utf-8") as file: @@ -166,6 +166,7 @@ def update_spm(): packages[metadata["id"]] = f"{API_ROOT}/packages/{pkg.name}" spm["packages"] = packages + spm["self"] = f"{API_ROOT}/spm.json" with open(ROOT / "spm.json", "w", encoding="utf-8") as file: json.dump(spm, file, indent=4) diff --git a/manifest.lua b/manifest.lua index b3e0434..b920163 100644 --- a/manifest.lua +++ b/manifest.lua @@ -670,4 +670,11 @@ printInline=function(...) end --- Prints text to stdout with format --- @param fmt string --- @param ... any -printf=function(fmt, ...) end \ No newline at end of file +printf=function(fmt, ...) end + +--- Gets input from fd +--- @param fd integer +--- @param helpstr string +--- @param replacechar string +--- @param fdo integer +userinput=function(fd, helpstr, replacechar, fdo) end \ No newline at end of file diff --git a/packages/Hyperion-core.pkg b/packages/Hyperion-core.pkg index 6936838..eefec1c 100644 --- a/packages/Hyperion-core.pkg +++ b/packages/Hyperion-core.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "e83a8dc42a871c1e16cd56c214cf0ca4bb0079432dc8bd198abbe11d6cf31d4e", + "hash": "e70a3cff68a821b6d1641553c2b1495e07930bcd5808db63e8768608a928339e", "tarball": "http://localhost:8000/packages/raw/Hyperion-core.tar.xz" } diff --git a/packages/Hyperion-firmware-ac.pkg b/packages/Hyperion-firmware-ac.pkg index e03bae2..88d88b7 100644 --- a/packages/Hyperion-firmware-ac.pkg +++ b/packages/Hyperion-firmware-ac.pkg @@ -8,6 +8,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "f64be830fc02394eeb9c049a528ed47b97430c6682a577c789d16303dcaad6fc", + "hash": "771fd62d79ff857a1ea1cf3caae340a40b08bc2330fcc6b012b9e07d001ddb45", "tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-ac.tar.xz" } diff --git a/packages/Hyperion-firmware-ccpc.pkg b/packages/Hyperion-firmware-ccpc.pkg index 8c3402a..f07ab29 100644 --- a/packages/Hyperion-firmware-ccpc.pkg +++ b/packages/Hyperion-firmware-ccpc.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "f3f030d6f6faa137f9950f0ce4ccc598a9b29c729380c100c920fad5aa254076", + "hash": "f79a5a9f657acc72bb97c7731c06e366f4118c8d5d5324f8e35a958f95be2796", "tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-ccpc.tar.xz" } diff --git a/packages/Hyperion-firmware-cct.pkg b/packages/Hyperion-firmware-cct.pkg index cbb3640..b03fe86 100644 --- a/packages/Hyperion-firmware-cct.pkg +++ b/packages/Hyperion-firmware-cct.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.3.0", - "hash": "dd69c26ba6f46acb99d6f839474fc50283524bd99df7f67a5d300a749af86dde", + "hash": "c2b234005baa8bee1b753b96808f0b326a7f035d65e52295cb93320d5a397886", "tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-cct.tar.xz" } diff --git a/packages/Hyperion-firmware-oc.pkg b/packages/Hyperion-firmware-oc.pkg index 2fafce2..d82a925 100644 --- a/packages/Hyperion-firmware-oc.pkg +++ b/packages/Hyperion-firmware-oc.pkg @@ -6,6 +6,6 @@ ], "dependencies": [], "version": "0.1.0", - "hash": "8b1bbff272dd07f0e5023c90007ec8d3a84f5b29a59449a75894319c86ee10cd", + "hash": "f7805a3934a09cc3384d82a20ade2adc81afa3e403055cda191bf5cdc31bcc2b", "tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-oc.tar.xz" } diff --git a/packages/Hyperion-kernel.pkg b/packages/Hyperion-kernel.pkg index 8a5e571..eea9d2c 100644 --- a/packages/Hyperion-kernel.pkg +++ b/packages/Hyperion-kernel.pkg @@ -8,6 +8,6 @@ ], "dependencies": [], "version": "1.5.0", - "hash": "a17552597f1a4e661804bcf23d26e19664cb6f75cb3058357603df59b033155a", + "hash": "68b8f1ae21a62e627bad1187b828c959c93454d1b75a29db00a1a31b187796d0", "tarball": "http://localhost:8000/packages/raw/Hyperion-kernel.tar.xz" } diff --git a/packages/bit32.pkg b/packages/bit32.pkg index 781736f..af56ce2 100644 --- a/packages/bit32.pkg +++ b/packages/bit32.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "9bc32da8ab97f899e85faeb47064433ef4a167e45924c0e583d30f901551bdf5", + "hash": "a92fbf2d886c1ee965b1d34aed8bcf5294d97fd0f55a981e82ba5d17171e99e9", "tarball": "http://localhost:8000/packages/raw/bit32.tar.xz" } diff --git a/packages/blake2s.pkg b/packages/blake2s.pkg index a085084..410d79d 100644 --- a/packages/blake2s.pkg +++ b/packages/blake2s.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "c32e2bbeba5d8609f720bce59fad0505d490ee22a6e54b4d830a524e609ac415", + "hash": "2ee62a46d32e3d302453d4cb04ac8af72771645b8120e1d827eeb47b599eb192", "tarball": "http://localhost:8000/packages/raw/blake2s.tar.xz" } diff --git a/packages/coreutils.pkg b/packages/coreutils.pkg index 7a48f19..8a30f89 100644 --- a/packages/coreutils.pkg +++ b/packages/coreutils.pkg @@ -8,6 +8,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "c52244c7fd2ca96780ed684327ebb55872757a4f6c8d90e18367ec4e0d8f10ad", + "hash": "dc2b541f3b9eaf8f0fd41afdaef95d2a2c37a05c01e1e6143dd0d17380f75340", "tarball": "http://localhost:8000/packages/raw/coreutils.tar.xz" } diff --git a/packages/deflate.pkg b/packages/deflate.pkg index 1b2b954..796fbee 100644 --- a/packages/deflate.pkg +++ b/packages/deflate.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.0.0-release", - "hash": "43a3df0e6da39aa97c0ee0ce4217e9acffadba4178d03dae5c66bf4627147644", + "hash": "e35f29c486d4a002e46b5c4e85676c480310829b606fc72d093ed86e7daab91d", "tarball": "http://localhost:8000/packages/raw/deflate.tar.xz" } diff --git a/packages/gfxterm.pkg b/packages/gfxterm.pkg index b9370a7..70a7b32 100644 --- a/packages/gfxterm.pkg +++ b/packages/gfxterm.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "88eb9f9bb7bb86fb7752601c67e4ab62e88fb7562057a83c101aaf7ffc3ccdc0", + "hash": "73515e60e945b7dc9e5adb34db499e52cec9a44ff688d30ce7600025572a3e4c", "tarball": "http://localhost:8000/packages/raw/gfxterm.tar.xz" } diff --git a/packages/hysh.pkg b/packages/hysh.pkg index ecf2170..9fc0284 100644 --- a/packages/hysh.pkg +++ b/packages/hysh.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.3.0", - "hash": "d0baaeb889eeaa38a9f100c4954b8f30c36c220ba73d8b8fa878e0fcaeaadb15", + "hash": "f01bd72d19c57a3a12c940fb2fd8d09b53a47eb857e09ecbca6464199dba35ae", "tarball": "http://localhost:8000/packages/raw/hysh.tar.xz" } diff --git a/packages/iniparse.pkg b/packages/iniparse.pkg index e8af038..6b47ddc 100644 --- a/packages/iniparse.pkg +++ b/packages/iniparse.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "f26f900027066dc2f498a4ccb8306f48c93210e7869b11f4aef9900f2e00e066", + "hash": "6a883872f8f1db19617b99aae58358dc603f54801b7cde035b603773f03c7ca1", "tarball": "http://localhost:8000/packages/raw/iniparse.tar.xz" } diff --git a/packages/installer.pkg b/packages/installer.pkg index 3e0ce3c..4785008 100644 --- a/packages/installer.pkg +++ b/packages/installer.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "8623a44260062d0066aecc683b45c2ea9e6f438fd74cef050e7bcac7daa33a4f", + "hash": "3d57052898dfbfcb645cc407523702d4df91675a17bd04754b6494c3e9d2a53b", "tarball": "http://localhost:8000/packages/raw/installer.tar.xz" } diff --git a/packages/json.pkg b/packages/json.pkg index 4655b87..77aeda2 100644 --- a/packages/json.pkg +++ b/packages/json.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "8344035d687f5cafb8c918d6bddd2ba5a7d6c2025aa43def84b942a614583282", + "hash": "f27f343ab85bb4dc8bd0ee6882a01aaaceeb38c791f672b54c2f1d6e80d4287e", "tarball": "http://localhost:8000/packages/raw/json.tar.xz" } diff --git a/packages/lua.pkg b/packages/lua.pkg index 1a0dd6d..3137f57 100644 --- a/packages/lua.pkg +++ b/packages/lua.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.2.0", - "hash": "69978317dbe981a50aa3194ed68d35bbd4d1e87ba03191aa7b3574712861e54c", + "hash": "0ce3793bcef753f01ced1d5db88f39840ffbbd15eb485e32ebfc9191f0f67360", "tarball": "http://localhost:8000/packages/raw/lua.tar.xz" } diff --git a/packages/micro.pkg b/packages/micro.pkg index e7b67cf..1702063 100644 --- a/packages/micro.pkg +++ b/packages/micro.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "20619f7885c20cef538842ad1a958dd5dfbd9a3542997acd7de91f89e57e32db", + "hash": "cb53fe713bb74dc76f66bac0d856525ab4aeb9ab9ac1c09ca1a674ad646378fd", "tarball": "http://localhost:8000/packages/raw/micro.tar.xz" } diff --git a/packages/minify.pkg b/packages/minify.pkg index 7c1c9b4..abbf410 100644 --- a/packages/minify.pkg +++ b/packages/minify.pkg @@ -8,6 +8,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "bbbc1c2137b76aec328bf8cc0d246f852af35943175fbcd8e1bf55fc9348e4ba", + "hash": "47f8e1658373657131d514af623e7cf74fdc3165e8d4c05634fd064eb1217ef8", "tarball": "http://localhost:8000/packages/raw/minify.tar.xz" } diff --git a/packages/pid.pkg b/packages/pid.pkg index 1309634..5d7421e 100644 --- a/packages/pid.pkg +++ b/packages/pid.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "b1941d2a2699774ab94886d866198219608544f63bee6cf2f059d5b1ed9c86e8", + "hash": "6736ecf743bbe3a09c223c7f73d5247056a103ec334813ada62f9bd50720f412", "tarball": "http://localhost:8000/packages/raw/pid.tar.xz" } diff --git a/packages/raw/Hyperion-core.tar.gz b/packages/raw/Hyperion-core.tar.gz index 8f353f4885ce562d91b555878804f6bf1929e7ec..5a758fa7d6d88ec19369ca08f0d5508a189daf6d 100644 GIT binary patch literal 2726 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 M-F4!-7%CVT0K9>X7ytkO literal 2885 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 diff --git a/packages/raw/Hyperion-firmware-ac.tar.gz b/packages/raw/Hyperion-firmware-ac.tar.gz index e56edb5f10ce44df6e1f27b36a37f239b27adc38..7754c5db7823688b5a6622177602553fcef09bb6 100644 GIT binary patch delta 16 XcmaDY@mhjizMF$%?VgN{>?u3|G_eK2 delta 16 XcmaDY@mhjizMF%iB_e4fdkPN#F&qUh diff --git a/packages/raw/Hyperion-firmware-ccpc.tar.gz b/packages/raw/Hyperion-firmware-ccpc.tar.gz index 699a5f74b732358b50c1d43504109495a0cbb5a5..cc8fcb16263e2f7dc041022312b9dbf099515fe1 100644 GIT binary patch delta 16 XcmZp0Yj9(i@8;lGyC-8K`%fhRE^h_$ delta 16 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 P??30FH>D$@Z#Nj`8PF}ZR&qLKR#QubC1D| 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 diff --git a/packages/raw/Hyperion-firmware-oc.tar.gz b/packages/raw/Hyperion-firmware-oc.tar.gz index 307ae1253813c274d61dfd05e0942edb02a3ebc7..d287eccd119f07c6eaa67557caee8207bee9879d 100644 GIT binary patch delta 16 XcmZqTXyRa(@8;lGyC-8K`)_6dC&&d| delta 16 XcmZqTXyRa(@8;lWiAdVW{+k&9Br^oc diff --git a/packages/raw/Hyperion-kernel.tar.gz b/packages/raw/Hyperion-kernel.tar.gz index 96b6b704f5320753db70a9328a3c33aedc84fded..0f5d8c54dca0bd008a63b8288ff44a46fe01302f 100644 GIT binary patch literal 34453 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 literal 34243 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 z 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 h3aj^C{dW2QyL`=ugQO4-`Gx<{)C8G#drA delta 16 Xcmey!^O1*LzMF%iB_e4fdlnl2Fop#p diff --git a/packages/raw/coreutils.tar.gz b/packages/raw/coreutils.tar.gz index cdea3977e134ce2f68f91b98bc7707c3268376a0..ef4288a7596c9abffac515c14009d6392062af62 100644 GIT binary patch delta 16 XcmdmPv)zVWzMF$%?VgN{>;`fGGBX8# delta 16 XcmdmPv)zVWzMF%iB_e4fyMY`4E}jJJ diff --git a/packages/raw/deflate.tar.gz b/packages/raw/deflate.tar.gz index 949dc532005a9feaba9ac08089223e114e3a4c99..afdd204e38b7e632f121e71e21c8c4e8f801a48c 100644 GIT binary patch delta 29059 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 OhIN}>M?ZrB69WL*ee+ZR delta 28983 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 delta 16 XcmaDU{8E@*zMF%iB_e4f`y);OF---V diff --git a/packages/raw/hysh.tar.gz b/packages/raw/hysh.tar.gz index ad57c17a101f4106240cc7bc37268c88b50efbb1..b5fb772602ab8249fc771346e2198280a61fed63 100644 GIT binary patch delta 27532 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�q)dv~xI)}+0vxw+=r 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 delta 27554 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 K+NKN_m>2+f&X{-r diff --git a/packages/raw/iniparse.tar.gz b/packages/raw/iniparse.tar.gz index 1e8f9e05d017c4af1daee796d6f3b1d03635b9bc..b10a53b5f732366f8b5b0852fedc8d6c6c9f4b7c 100644 GIT binary patch delta 16 XcmX@bc8ZN%zMF$%?VgN{?9R*pE|3K= delta 16 XcmX@bc8ZN%zMF%iB_e4fyE8KYD*FVU diff --git a/packages/raw/installer.tar.gz b/packages/raw/installer.tar.gz index 5899892a6f7a95f624de8d3a4d90becd0dabf334..5a6e1c9f3f33a65ed905ce6e7ba873e35713b3ec 100644 GIT binary patch delta 16 XcmeBV>11J-@8;lGyC-8KI};NCCN~6W delta 16 XcmeBV>11J-@8;lWjY!(a&cp-&BB=w{ diff --git a/packages/raw/json.tar.gz b/packages/raw/json.tar.gz index 61605b1ae16c860a51af7a0d3c1066b543dc7409..93af1a3fd595f58c2b50b49750a33460f447348c 100644 GIT binary patch delta 16 XcmZpcX_jG^@8;lGyC-8K`yXBaDk24v delta 16 XcmZpcX_jG^@8;lWjY!(a{)ZO;CX@vL diff --git a/packages/raw/lua.tar.gz b/packages/raw/lua.tar.gz index 8b334956fc12660311e75846d808c6dd8a392bc3..20616723e3cec4d927921e75de5df26429192939 100644 GIT binary patch delta 16 XcmdlizFC}IzMF$%?VgN{>}$9IE|dk9 delta 16 XcmdlizFC}IzMF%iH6m#v`xU#G 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 delta 13087 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

8wmILGU*D>?>^^s#(}bt-!!EY7`fK|Q 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 GU;qFPWzDSs literal 1370 zcmb2|=HO_JNXlaRUyzxiSCUx7@HQ$p|F#>?xAgyA&Gt7}u6=Q}s5$M%2HqD9rP>=3 zxyd>6T`c==Y<-#^bH31QTlS58k7vCr zY5MX<^Xb8-8{aE--}-J-xuxcONPq6x=y|-E&m-d^|8IM}M*WC&>fg&c;+{T_A2i%c z{`6l{@;~RF^7bG3%KzrG{5O~Sw>zM+?RCD{zNZPy7Q%m)yZ%!YoH_CR=fzk5-zw#Q zyg%3cN4~Y*nWkyG<8})t&D-?vyvYCf`^$YksLZSTZgai8<*)qj|CfL5|9q)>r&;ac zt-0Bc^EdpT@A;oU!>|9Rz>h1>?ayyZ2>7t@pX~9kAAjhiY{!snxjUQMaL_VxP zk>7Wf`Jdgt-P4{b{!@m)xjg?LwhM}Vk@)(*^?QBx_2};(?ic&Y-~T_iDQxv>bDL+o zf3LopWyL#LmzQ%1<4!gH`OA#t@9lkDc;MTChWOrN>pHeu`X_DT&75-XeMZCv)y@L} zAua_@-#?`osyftM=iqSZpR(&o=;_n;8+KfotP&B|v18)Y95ME_Gf%BadNzBSdDgN? znQ2*pl|Ms_erqp^Jm&JxTkx*IMID`Gg4yDe?=N2?q;ukVwo$kD)tT=Yg_Q(9OSZh} zI@6IjMeRwUo6-r3qQe}jU#E7v%jCpPzAd=f{`vNolkOD#;GU-9xm06yPR2g(wKsFE zq=gGLA1z+w(8VM$b<-`IH+99+IA%&N-OzQ%taG8!p$VK9PDRLVl=<*PE#-5&nap<0 z69*Rd9aL@B=9yVk@Oc{Jv`a0=E6cMNr#AAZEuSe;8TDks(XOo1(km|h4d{JmZMxz7 zJ#ML2-$dSZtV#=hShh;>!0~<~b%%>GQ5SXw{p4L7sTgtO6vq*pD@XTF>*Lq|EgQ9S z)&ES*&CBkcvD&(eSNhrYsR;s4E2m0Ga+kL~t2`cNdwnYVyw{J;70H+yG`0I=*VTh+&ER!%gc26jYW@Lpu(w&`P=U zSZkI2=Z@y%{f|C8H#(=9^s;Yj__}Yf+^u&lYi=R?3SymNB7zRq;RVw#b81>t!-n3-(p52sH_5T6?!h zB2U(to$-3%=YkX6B5J{A{ZdvGwq%EDSOQirj^1bN*uuxPOHvrZ)V^+d+RFaXVJ;u@Mf_LK^m@K8z&B1{XItHp>CF%HMEV~* zoOl1?ockNasuEvX{nFZb?U>{4ymb~EUu|t?-N~~3Skpw4j{6LETX)S6*S!-v;omIj zJG%q!%qZKtr#JL#@y*p=Q`hf#t!MEfYp!v8R?6bt%S^Yta$6jmyUzH@pG^&49rs*0 z79%YocF3&LpHFIQ7FTXht>UmUd2Z6M?ws|lgy6XF<8F5UZ1z8|XWsw+*!%tL_y7NV zZMyHD_5APkI=8vv?Dok$l|JCU|NrMR_rBN5&3W*9fAEFqiAy>sMDy#ef7$+|J?|Cw z&)x-(N?ArWy`ZS7{B~q?vrx-)nETt|Cfb-ufP6vZt2gz h`}^YSoF3OOTSH@H$2*~_WR+) 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 delta 16 XcmdnawVjJyzMF%iH6m#vy8$ZzDHH^7 diff --git a/packages/raw/tar.tar.gz b/packages/raw/tar.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..7ac10cf625faf027f1009588b1ec71632013308e GIT binary patch literal 1795 zcmb2|=HOVnCnJmLe@SAIUP)pR!`qnG`M1pk&ZqwuZP~>bwD{DdHSMxz4!4PBu!}hF z=aINj(wcK|n?UrZFE1vE{k>oA9;EMGHmR&^`z&^oZ6}l~&)=7wYjx~`#J?|AJ8C_f zCoB_pSDbu#U-)I2-dEo(@@8&Jjh%42TR33iQ%A1j@pIH~+TDC|vCU7n{*8~@zZ1ng z>`}Z>w|sd${rZfhFH!#p8AFo6cSzdM!?2Uhkuie z?;{1i?;q}(|F>6lezgC{f3E*`JMCvm2v@8oAbLBo@svm@AL8h)4S7_1q$)k{WJSIS>^TqHUIhd|F`T*{*iot zb8Y1R^GpA=JIcv?7Wy&c_x$${{^mb9Fk#Ps&p*?D{15$5pJP4m$p6iU{zr<)uV%B6 z`!9QX>JR;o@sIW&srOudxc*Fw^3(qZ&;Q@`9kq@!~Jp}?{ELrmy{auUwaa2Qtc=HT48yLSJ1C;!KERguL51A3*0t{ z7S#MP5jfwiH1Bz!(Bxc!UDMVcyVbz3)I|T%jGU&L)H9h|!jg?t4AxIv{=;ZN;fDlD@+?aQH-SV?#DZ69S zSuFKD>hcMXsgH7|p8K-q==vVt>ymFh_H|qUt^Xy;-r>mrmkNaGkgSrM) zBEHre*mg>>X~c@Q3Glwq)H;7w8T5? zGnn$E`mUWS5oE2=Jz>RvASp{k!uqA-g>_g zS@YemK`Z`L*MqA<59L+N=QX|Qy0ogaQb>HZ(knRIc5T!G4+S0CCA=#mD|@UFrjd7=e=(Q zI+GTK{FPfE{OHY5tA{Gv&OBiE-^tMNyygdk&URIXg${Y!R!mQ3n^=B%rlbBlJN~jK z-3K?<{J;13^kVyOa<}E#e1*i)_eSYEt2@lPBAc0bxR1L;Z*5t`bE}>m>#HUC<%8Xy z`^`&eXKy^w{*Ns`@X&0#>zhvS2geD`Y7F|mBGhQ}x6M&kSC~IoBg*ETZ+`o0oV7~S zt*w(5zR6hl_0q4#RTupd@7v`bniIjxyVUg4me_x@J6QV@n*QCdN-MoD}rw*K>Q9$Wsxo_WXET9>G~EV$HP7h09`ETjb@SKPen%qgfTVR>f?S zkN=u7cY?Y<_pN-piKad4H%HwNQ(7`P>*~sP^J0#N{`XtQ>CU(Rao(RbSF)E2<{M~< zzR?d{nB%ig#HcF$^>49z8V@cND6Hbw_+2?`quSSuEK|d#gUxH-KTVxJjjLKudi&?U z47U%S+H~~jqNwjVXAgB0M~JMhK7Lh5&-L@vReOFG|M(X4Qny>TL{wBh{+;8y!@f@4 zbD0ZM)qZI1`h1ILx36rr){TUlGgx2Ne_tH(^LPBu-}kS5-=BN?!`n{n{r_v-=KsH( zGtVu0kAv(}>xTZH|LxatMWdWMBx4^%J&FfafBP%xU4 literal 0 HcmV?d00001 diff --git a/packages/raw/xz.tar.gz b/packages/raw/xz.tar.gz index bc7601c31ee75e161caefe60a20fe011c4d5603c..559c0de3979073b1cf6a037d0714dd489352e718 100644 GIT binary patch delta 16 XcmcZ^aWjHlzMF$%?VgN{>_IvJIgth{ delta 16 XcmcZ^aWjHlzMF%iH6m#vdyozQHUkBj diff --git a/packages/spm.pkg b/packages/spm.pkg index e13a16a..ef9d1ea 100644 --- a/packages/spm.pkg +++ b/packages/spm.pkg @@ -5,8 +5,12 @@ "Hyperion", "Astronand" ], - "dependencies": [], + "dependencies": [ + "tar", + "deflate", + "json" + ], "version": "1.0.0", - "hash": "55f9a95f5fd032f6a9ad27c9528987f9051554d506f1dddb4494daf822db5e1b", + "hash": "26d7cf304ad0bc36fbfa80af1b7af957de29a6c233e6d8a302b2b562f78326db", "tarball": "http://localhost:8000/packages/raw/spm.tar.xz" } diff --git a/packages/sysinit.pkg b/packages/sysinit.pkg index 6574ab4..5e8da6d 100644 --- a/packages/sysinit.pkg +++ b/packages/sysinit.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.1.0", - "hash": "f4a3947d96d85bae5c43342567ed87fae99d1f4e692e99f42df8cec7cb556451", + "hash": "379cae7a2c42b5b0c30476c7660148c60ac426664627c649060c8feca01aa33f", "tarball": "http://localhost:8000/packages/raw/sysinit.tar.xz" } diff --git a/packages/tar.pkg b/packages/tar.pkg new file mode 100644 index 0000000..dfafd3f --- /dev/null +++ b/packages/tar.pkg @@ -0,0 +1,12 @@ +{ + "id": "tar", + "description": "", + "authors": [ + "Hyperion", + "Astronand" + ], + "dependencies": [], + "version": "", + "hash": "2549429f0686c88354b091cbbd0cd7f80148115178cb3e5198924de28c7da6f4", + "tarball": "http://localhost:8000/packages/raw/tar.tar.xz" +} diff --git a/packages/xz.pkg b/packages/xz.pkg index 005b0a5..526b50f 100644 --- a/packages/xz.pkg +++ b/packages/xz.pkg @@ -10,6 +10,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "1b5d564b4fea1af5a5e3fde1790298b9f9e7182ad2697b936bc551acffa2beef", + "hash": "38422b0eb99cef1122d4aeb3472e705ba304f58713280449bd3a6a492bacd521", "tarball": "http://localhost:8000/packages/raw/xz.tar.xz" } diff --git a/spm.json b/spm.json index fa76415..56648e5 100644 --- a/spm.json +++ b/spm.json @@ -21,12 +21,15 @@ "pid": "http://localhost:8000/packages/pid.pkg", "spm": "http://localhost:8000/packages/spm.pkg", "sysinit": "http://localhost:8000/packages/sysinit.pkg", + "tar": "http://localhost:8000/packages/tar.pkg", "xz": "http://localhost:8000/packages/xz.pkg" }, "refs": [ - "https://git.astronand.dev/Astronand/HyperionOS-packages/raw/branch/main/spm.json" + "https://git.astronand.dev/Astronand/HyperionOS-packages/raw/branch/main/spm.json", + "http://localhost:8001/spm.json" ], "maintainers": [ "Hyperion" - ] + ], + "self": "http://localhost:8000/spm.json" } -- 2.55.0 From 10aa0c62ff45219d9ee84976bf0ee53ce76abead Mon Sep 17 00:00:00 2001 From: Astronand Date: Fri, 14 Aug 2026 20:44:11 -0400 Subject: [PATCH 6/6] spm works maybe? --- .vscode/settings.json | 3 + .../data/lib/modules/31_keyboards.kmod | 9 + .../data/lib/modules/ccpc/25_gfx.kmod | 394 +---------- .../data/boot/cct/boot.lua | 88 ++- .../lib/modules/cc-tweaked/01_periph.kmod | 53 +- .../lib/modules/cc-tweaked/13_devraw.kmod | 26 + .../data/lib/modules/cc-tweaked/22_http.kmod | 9 +- .../data/lib/modules/cc-tweaked/25_tty.kmod | 1 - .../{30_deamon.kmod => 30_daemon.kmod} | 14 +- Src/Hyperion-kernel/data/boot/kernel.lua | 43 +- .../data/lib/modules/hyperion/10_vfs.kmod | 13 +- .../data/lib/modules/hyperion/12_devfs.kmod | 16 +- .../lib/modules/hyperion/45_hypervisor.kmod | 1 - .../hyperion/{47_dbg.kmod => 48_dbg.kmod} | 0 .../data/lib/modules/hyperion/90_kgc.kmod | 3 +- Src/gfxterm/data/lib/gfx | 84 +++ Src/gfxterm/data/lib/psf | 232 +++++++ .../test/usr/local/gfxterm/tests/uv.lsl | 0 Src/hysh/data/bin/hysh | 8 +- Src/hysh/data/bin/redirect | 14 + Src/minify/data/lib/minify | 24 +- Src/spm/data/bin/spm | 448 ++++++++++++- Src/spm/dependencies.txt | 4 +- Src/tar/data/lib/tar | 1 + bootstrap/cct-bootstrap.lua | 609 ++++++++++++++++++ compile.py | 2 +- install.lua | 15 + out | Bin 0 -> 3904 bytes packages/Hyperion-core.pkg | 4 +- packages/Hyperion-firmware-ac.pkg | 4 +- packages/Hyperion-firmware-addon-cct.pkg | 9 + packages/Hyperion-firmware-ccpc.pkg | 4 +- packages/Hyperion-firmware-cct.pkg | 4 +- packages/Hyperion-firmware-lua.pkg | 9 + packages/Hyperion-firmware-oc.pkg | 4 +- packages/Hyperion-firmware-vm.pkg | 9 + packages/Hyperion-kernel.pkg | 4 +- packages/bit32.pkg | 4 +- packages/blake2s.pkg | 4 +- packages/coreutils.pkg | 4 +- packages/deflate.pkg | 4 +- packages/gfxterm.pkg | 4 +- packages/hysh.pkg | 4 +- packages/iniparse.pkg | 4 +- packages/installer.pkg | 4 +- packages/json.pkg | 4 +- packages/lua.pkg | 4 +- packages/micro.pkg | 4 +- packages/minify.pkg | 4 +- packages/pid.pkg | 4 +- packages/raw/Hyperion-core.tar.gz | Bin 2726 -> 2631 bytes packages/raw/Hyperion-firmware-ac.tar.gz | Bin 3179 -> 3117 bytes .../raw/Hyperion-firmware-addon-cct.tar.gz | Bin 0 -> 473 bytes packages/raw/Hyperion-firmware-ccpc.tar.gz | Bin 8960 -> 7171 bytes packages/raw/Hyperion-firmware-cct.tar.gz | Bin 11536 -> 12190 bytes packages/raw/Hyperion-firmware-lua.tar.gz | Bin 0 -> 213 bytes packages/raw/Hyperion-firmware-oc.tar.gz | Bin 1026 -> 990 bytes packages/raw/Hyperion-firmware-vm.tar.gz | Bin 0 -> 210 bytes packages/raw/Hyperion-kernel.tar.gz | Bin 34453 -> 34613 bytes packages/raw/bit32.tar.gz | Bin 1170 -> 1094 bytes packages/raw/blake2s.tar.gz | Bin 1649 -> 1607 bytes packages/raw/coreutils.tar.gz | Bin 7735 -> 7584 bytes packages/raw/deflate.tar.gz | Bin 29691 -> 29604 bytes packages/raw/gfxterm.tar.gz | Bin 2537 -> 5503 bytes packages/raw/hysh.tar.gz | Bin 27951 -> 28385 bytes packages/raw/iniparse.tar.gz | Bin 842 -> 797 bytes packages/raw/installer.tar.gz | Bin 521 -> 466 bytes packages/raw/json.tar.gz | Bin 3587 -> 3525 bytes packages/raw/lua.tar.gz | Bin 2995 -> 2946 bytes packages/raw/micro.tar.gz | Bin 3989 -> 3932 bytes packages/raw/minify.tar.gz | Bin 16398 -> 16411 bytes packages/raw/pid.tar.gz | Bin 1387 -> 1341 bytes packages/raw/spm.tar.gz | Bin 2956 -> 5885 bytes packages/raw/sysinit.tar.gz | Bin 1335 -> 1268 bytes packages/raw/tar.tar.gz | Bin 1795 -> 1767 bytes packages/raw/xz.tar.gz | Bin 11353 -> 11288 bytes packages/spm.pkg | 9 +- packages/sysinit.pkg | 4 +- packages/tar.pkg | 4 +- packages/xz.pkg | 4 +- spm.json | 3 + spm.tar.gz | Bin 0 -> 3933 bytes 82 files changed, 1706 insertions(+), 535 deletions(-) create mode 100644 Src/Hyperion-firmware-addon-cct/data/lib/modules/31_keyboards.kmod create mode 100644 Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/13_devraw.kmod rename Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/{30_deamon.kmod => 30_daemon.kmod} (88%) rename Src/Hyperion-kernel/data/lib/modules/hyperion/{47_dbg.kmod => 48_dbg.kmod} (100%) create mode 100644 Src/gfxterm/data/lib/gfx create mode 100644 Src/gfxterm/data/lib/psf create mode 100644 Src/gfxterm/test/usr/local/gfxterm/tests/uv.lsl create mode 100644 Src/hysh/data/bin/redirect create mode 100644 bootstrap/cct-bootstrap.lua create mode 100644 install.lua create mode 100644 out create mode 100644 packages/Hyperion-firmware-addon-cct.pkg create mode 100644 packages/Hyperion-firmware-lua.pkg create mode 100644 packages/Hyperion-firmware-vm.pkg create mode 100644 packages/raw/Hyperion-firmware-addon-cct.tar.gz create mode 100644 packages/raw/Hyperion-firmware-lua.tar.gz create mode 100644 packages/raw/Hyperion-firmware-vm.tar.gz create mode 100644 spm.tar.gz diff --git a/.vscode/settings.json b/.vscode/settings.json index 1c1fd9a..710e125 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,5 +8,8 @@ "toHex", "loadcstr", "userinput" + ], + "Lua.diagnostics.disable": [ + "need-check-nil" ] } \ No newline at end of file diff --git a/Src/Hyperion-firmware-addon-cct/data/lib/modules/31_keyboards.kmod b/Src/Hyperion-firmware-addon-cct/data/lib/modules/31_keyboards.kmod new file mode 100644 index 0000000..9bb5fa7 --- /dev/null +++ b/Src/Hyperion-firmware-addon-cct/data/lib/modules/31_keyboards.kmod @@ -0,0 +1,9 @@ +--:Minify:-- +local kernel=... + +local kbs = {kernel.cct.peripheral.find("tm_keyboard")} + + +kernel.cct.eventhooks["tm_keyboard_char"]=function(...) + +end \ No newline at end of file diff --git a/Src/Hyperion-firmware-ccpc/data/lib/modules/ccpc/25_gfx.kmod b/Src/Hyperion-firmware-ccpc/data/lib/modules/ccpc/25_gfx.kmod index 94edf54..9a6481b 100644 --- a/Src/Hyperion-firmware-ccpc/data/lib/modules/ccpc/25_gfx.kmod +++ b/Src/Hyperion-firmware-ccpc/data/lib/modules/ccpc/25_gfx.kmod @@ -1,394 +1,6 @@ --:Minify:-- -local kernel = ... -local apis = kernel.apis -local native = apis.peripheral -local sides = {"top", "bottom", "left", "right", "front", "back"} -local peripheral={} +local kernel=... -function peripheral.getNames() - local results = {} - for n = 1, #sides do - local side = sides[n] - if native.isPresent(side) then - table.insert(results, side) - if native.hasType(side, "peripheral_hub") then - local remote = native.call(side, "getNamesRemote") - for _, name in ipairs(remote) do - table.insert(results, name) - end - end - end - end - return results -end - -function peripheral.isPresent(name) - if native.isPresent(name) then - return true - end - - for n = 1, #sides do - local side = sides[n] - if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then - return true - end - end - return false -end - -function peripheral.getType(peripheral) - if type(peripheral) == "string" then - if native.isPresent(peripheral) then - return native.getType(peripheral) - end - for n = 1, #sides do - local side = sides[n] - if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then - return native.call(side, "getTypeRemote", peripheral) - end - end - return nil - else - local mt = getmetatable(peripheral) - if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then - error("bad argument #1 (table is not a peripheral)", 2) - end - return table.unpack(mt.types) - end -end - -function peripheral.hasType(peripheral, peripheral_type) - if type(peripheral) == "string" then - if native.isPresent(peripheral) then - return native.hasType(peripheral, peripheral_type) - end - for n = 1, #sides do - local side = sides[n] - if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then - return native.call(side, "hasTypeRemote", peripheral, peripheral_type) - end - end - return nil - else - local mt = getmetatable(peripheral) - if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then - error("bad argument #1 (table is not a peripheral)", 2) - end - return mt.types[peripheral_type] ~= nil - end -end - -function peripheral.getMethods(name) - if native.isPresent(name) then - return native.getMethods(name) - end - for n = 1, #sides do - local side = sides[n] - if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then - return native.call(side, "getMethodsRemote", name) - end - end - return nil -end - -function peripheral.getName(peripheral) - local mt = getmetatable(peripheral) - if not mt or mt.__name ~= "peripheral" or type(mt.name) ~= "string" then - error("bad argument #1 (table is not a peripheral)", 2) - end - return mt.name -end - -function peripheral.call(name, method, ...) - if native.isPresent(name) then - return native.call(name, method, ...) - end - - for n = 1, #sides do - local side = sides[n] - if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then - return native.call(side, "callRemote", name, method, ...) - end - end - return nil -end - -function peripheral.wrap(name) - local methods = peripheral.getMethods(name) - if not methods then - return nil - end - - local types = { peripheral.getType(name) } - for i = 1, #types do types[types[i]] = true end - local result = setmetatable({}, { - __name = "peripheral", - name = name, - type = types[1], - types = types, - }) - for _, method in ipairs(methods) do - result[method] = function(...) - return peripheral.call(name, method, ...) - end - end - return result -end - -function peripheral.find(ty, filter) - local results = {} - for _, name in ipairs(peripheral.getNames()) do - if peripheral.hasType(name, ty) then - local wrapped = peripheral.wrap(name) - if filter == nil or filter(name, wrapped) then - table.insert(results, wrapped) - end - end - end - return table.unpack(results) -end - -local icolors = { - [0x1] = 1, -- #000000 - [0x2] = 2, -- #FFFFFF - [0x4] = 3, -- #FF0000 - [0x8] = 4, -- #00FF00 - [0x10] = 5, -- #0000FF - [0x20] = 6, -- #00FFFF - [0x40] = 7, -- #FF00FF - [0x80] = 8, -- #FFFF00 - [0x100] = 9, -- #FF6D00 - [0x200] = 10, -- #6DFF55 - [0x400] = 11, -- #24FFFF - [0x800] = 12, -- #924900 - [0x1000] = 13, -- #6D6D55 - [0x2000] = 14, -- #DBDBAA - [0x4000] = 15, -- #6D00FF - [0x8000] = 16 -- #B6FF00 -} - -local colors = { - 0x0001, -- #000000 - 0x0002, -- #FFFFFF - 0x0004, -- #FF0000 - 0x0008, -- #00FF00 - 0x0010, -- #0000FF - 0x0020, -- #00FFFF - 0x0040, -- #FF00FF - 0x0080, -- #FFFF00 - 0x0100, -- #FF6D00 - 0x0200, -- #6DFF55 - 0x0400, -- #24FFFF - 0x0800, -- #924900 - 0x1000, -- #6D6D55 - 0x2000, -- #DBDBAA - 0x4000, -- #6D00FF - 0x8000 -- #B6FF00 -} - -local function write(text, term) - local x, y = term.getCursorPos() - local w, h = term.getSize() - - for i = 1, #text do - local c = text:sub(i, i) - - if c == "\n" then - y = y + 1 - x = 1 - elseif c == "\t" then - local tabSize = 4 - local spaces = tabSize - ((x - 1) % tabSize) - term.write(string.rep(" ", spaces)) - x = x + spaces - elseif c == "\b" then - if x > 1 then - x = x - 1 - term.setCursorPos(x, y) - term.write(" ") - term.setCursorPos(x, y) - end - else - if x <= w and y <= h then - term.setCursorPos(x, y) - term.write(c) - x = x + 1 - end - end - - if x > w then - x = 1 - y = y + 1 - end - - if y - 1 >= h then - term.scroll(1) - y = h - term.setCursorPos(x, y) - end - end - - term.setCursorPos(x, y) -end - -kernel.devfs.data.tty={} -local ctrl,alt = false, false - -local function serializeBool(bool) - if bool then - return "T" - else - return "F" - end -end - -local function newtty(obj, id, ev) - kernel.devfs.data["tty"][id] = function(op, mode) - if op=="type" then - return "character device" - elseif op=="open" then - local h = { - read=function(amount) - local rv="" - for i=1, amount or 1 do - local event = {ev()} - if event[1] then - rv=rv..event[1] - end - end - if rv=="" then rv=nil end - return rv - end, - write=function(content) - write(content, obj) - end, - size=function() - local s={obj.getSize()} - return table.concat(s,";") - end, - clear=function() - obj.clear() - obj.setCursorPos(1,1) - end, - gpos=function() - local s={obj.getCursorPos()} - return table.concat(s,";") - end, - spos=function(x,y) - return obj.setCursorPos(x,y) - end, - sfgc=function(c) - return obj.setTextColor(colors[c]) - end, - sbgc=function(c) - return obj.setBackgroundColor(colors[c]) - end, - gfgc=function() - return icolors[obj.getTextColor()] - end, - gbgc=function() - return icolors[obj.getBackgroundColor()] - end, - gctrl=function() - return serializeBool(ctrl)..";"..serializeBool(alt) - end - } - if mode=="rw" then - return h - elseif mode=="r" then - h["write"]=nil - return h - elseif mode=="w" then - h["read"]=nil - return h - end - end - end -end - -local fifo = kernel.newFifo() - -kernel.processes.cctmond = function() - local timeout = false - while true do - local event = {kernel.EFI:getMachineEvent()} - - if event[1] then - local eventType = event[1] - local charOrKey = event[3] - - local ctrlKeyMap = { - [apis.keys.a]=1, [apis.keys.b]=2, [apis.keys.c]=3, - [apis.keys.d]=4, [apis.keys.e]=5, [apis.keys.f]=6, - [apis.keys.g]=7, [apis.keys.h]=8, [apis.keys.i]=9, - [apis.keys.j]=10, [apis.keys.k]=11, [apis.keys.l]=12, - [apis.keys.m]=13, [apis.keys.n]=14, [apis.keys.o]=15, - [apis.keys.p]=16, [apis.keys.q]=17, [apis.keys.r]=18, - [apis.keys.s]=19, [apis.keys.t]=20, [apis.keys.u]=21, - [apis.keys.v]=22, [apis.keys.w]=23, [apis.keys.x]=24, - [apis.keys.y]=25, [apis.keys.z]=26, - } - - if eventType == "keyPressed" then - if charOrKey == apis.keys.leftCtrl or charOrKey == apis.keys.rightCtrl then - ctrl = true - elseif charOrKey == apis.keys.leftAlt or charOrKey == apis.keys.rightAlt then - alt = true - end - - if ctrl then - local ctrlByte = ctrlKeyMap[charOrKey] - if ctrlByte then - if ctrlByte == 3 then - for _, task in ipairs(syscall.getTasks()) do - syscall.sigsend(task, 1) - end - else - fifo.push(string.char(ctrlByte)) - end - end - else - local specialKeyMap = { - [apis.keys.up] = "", - [apis.keys.down] = "", - [apis.keys.right] = "", - [apis.keys.left] = "", - [apis.keys.home] = "", - [apis.keys["end"]] = "", - [apis.keys.pageUp] = "[5~", - [apis.keys.pageDown] = "[6~", - [apis.keys.delete] = "[3~", - } - local special = specialKeyMap[charOrKey] - if special then fifo.push(special) end - end - - elseif eventType == "keyReleased" then - if charOrKey == apis.keys.leftCtrl or charOrKey == apis.keys.rightCtrl then - ctrl = false - elseif charOrKey == apis.keys.leftAlt or charOrKey == apis.keys.rightAlt then - alt = false - end - - elseif eventType == "keyTyped" then - if charOrKey then fifo.push(charOrKey) end - end - - timeout = false - else - timeout = true - end - - if timeout then - sleep(0.05) - end - end -end - -newtty(apis.term, "1", fifo.pop) - -for i,v in ipairs({peripheral.find("monitor")}) do - v.setTextScale(.5) - v.write("Initializing...") - newtty(v,tostring(i+1),function () end) +if kernel.gfx then + end \ No newline at end of file diff --git a/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua b/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua index 2ac417b..e489239 100644 --- a/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua +++ b/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua @@ -55,11 +55,12 @@ local function displaySuperBadError(err) lterm.write("A critical error occurred while loading the system:") lterm.setCursorPos(1, 3) write(err, lterm) - while true do end + coroutine.yield("key") end term.setCursorBlink(false) local ok, err = xpcall(function() + --p local apis = {BOOT_DRIVE_PATH = BOOT_DRIVE_PATH} local lua = { @@ -100,6 +101,7 @@ local ok, err = xpcall(function() _G[i] = nil end end + --p local acekeys={ [apis.keys.enter]="\n", @@ -248,11 +250,12 @@ local ok, err = xpcall(function() return value end - local peripheral={} + --p + local p={} local native = apis.peripheral local sides = {"top", "bottom", "left", "right", "front", "back"} - function peripheral.getNames() + function p.getNames() local results = {} for n = 1, #sides do local side = sides[n] @@ -269,7 +272,7 @@ local ok, err = xpcall(function() return results end - function peripheral.isPresent(name) + function p.isPresent(name) if native.isPresent(name) then return true end @@ -283,7 +286,7 @@ local ok, err = xpcall(function() return false end - function peripheral.getType(peripheral) + function p.getType(peripheral) if type(peripheral) == "string" then if native.isPresent(peripheral) then return native.getType(peripheral) @@ -304,7 +307,7 @@ local ok, err = xpcall(function() end end - function peripheral.hasType(peripheral, peripheral_type) + function p.hasType(peripheral, peripheral_type) if type(peripheral) == "string" then if native.isPresent(peripheral) then return native.hasType(peripheral, peripheral_type) @@ -325,7 +328,7 @@ local ok, err = xpcall(function() end end - function peripheral.getMethods(name) + function p.getMethods(name) if native.isPresent(name) then return native.getMethods(name) end @@ -338,7 +341,7 @@ local ok, err = xpcall(function() return nil end - function peripheral.getName(peripheral) + function p.getName(peripheral) local mt = getmetatable(peripheral) if not mt or mt.__name ~= "peripheral" or type(mt.name) ~= "string" then error("bad argument #1 (table is not a peripheral)", 2) @@ -346,7 +349,7 @@ local ok, err = xpcall(function() return mt.name end - function peripheral.call(name, method, ...) + function p.call(name, method, ...) if native.isPresent(name) then return native.call(name, method, ...) end @@ -360,13 +363,13 @@ local ok, err = xpcall(function() return nil end - function peripheral.wrap(name) - local methods = peripheral.getMethods(name) + function p.wrap(name) + local methods = p.getMethods(name) if not methods then return nil end - local types = { peripheral.getType(name) } + local types = { p.getType(name) } for i = 1, #types do types[types[i]] = true end local result = setmetatable({}, { __name = "peripheral", @@ -376,17 +379,17 @@ local ok, err = xpcall(function() }) for _, method in ipairs(methods) do result[method] = function(...) - return peripheral.call(name, method, ...) + return p.call(name, method, ...) end end return result end - function peripheral.find(ty, filter) + function p.find(ty, filter) local results = {} - for _, name in ipairs(peripheral.getNames()) do - if peripheral.hasType(name, ty) then - local wrapped = peripheral.wrap(name) + for _, name in ipairs(p.getNames()) do + if p.hasType(name, ty) then + local wrapped = p.wrap(name) if filter == nil or filter(name, wrapped) then table.insert(results, wrapped) end @@ -394,8 +397,8 @@ local ok, err = xpcall(function() end return table.unpack(results) end - - local allscreens = {peripheral.find("monitor")} + --p + local allscreens = {p.find("monitor")} for i=1, #allscreens do allscreens[i].setTextScale(.5) allscreens[i].clear() @@ -404,6 +407,17 @@ local ok, err = xpcall(function() allscreens[#allscreens+1] = apis.term + local callAsyncQueue = {} + local callAsyncReturn = {} + apis.callAsyncReturn = callAsyncReturn + local callidx=0 + + function apis.callAsync(func, ...) + callidx=callidx+1 + callAsyncQueue[#callAsyncQueue+1] = {callidx, func, ...} + return callidx + end + local EFI = { getEpochMs = function() return apis.os.epoch("utc") end, getUptime = function() return apis.os.clock() * 1000 end, @@ -489,7 +503,8 @@ local ok, err = xpcall(function() apis.term.setCursorPos(1, 1) local kernelCoro = coroutine.create(function() - ---@diagnostic disable-next-line: param-type-mismatch + --pf + ---@diagnostic disable-next-line: param-type-mismatch- local ok, err = xpcall(Kernel, debug.traceback, EFI) if not ok and not EFI.reboot then displaySuperBadError(err) end if err then @@ -518,6 +533,7 @@ local ok, err = xpcall(function() end EFI.screenCtl:print("Loaded in " .. tostring(apis.os.clock()) .. " seconds.\n") + --p while true do local status, err = coroutine.resumeWithTimeout(kernelCoro, 50) @@ -526,28 +542,30 @@ local ok, err = xpcall(function() while not exit do local event = {coroutine.yield()} if event[1] == "key" then + queueEvent(table.unpack(event)) queueEvent("keyPressed", 1, event[2]) if acekeys[event[2]] then queueEvent("keyTyped", 1, acekeys[event[2]]) end elseif event[1] == "char" then + queueEvent(table.unpack(event)) queueEvent("keyTyped", 1, event[2]) elseif event[1] == "key_up" then + queueEvent(table.unpack(event)) queueEvent("keyReleased", 1, event[2]) - elseif event[1] == "disk" then - queueEvent("componentAdded", "disk") - elseif event[1] == "disk_eject" then - queueEvent("componentRemoved", "disk") - elseif event[1] == "modem_message" then - queueEvent("modem_message", table.unpack(event, 2)) - elseif event[1] == "rednet_message" then - queueEvent("rednet_message", table.unpack(event, 2)) - elseif event[1] == "http_success" then - queueEvent("http_success", table.unpack(event, 2)) - elseif event[1] == "http_failure" then - queueEvent("http_failure", table.unpack(event, 2)) elseif event[1] == "NoSleep" then exit = true + else + queueEvent(table.unpack(event)) + end + end + while #callAsyncQueue>0 do + local bundle = table.remove(callAsyncQueue, 1) + local ret = {xpcall(bundle[2], debug.traceback, table.unpack(bundle, 3))} + if not ret[1] then + callAsyncReturn[bundle[1]]={false, ret[2]} + else + callAsyncReturn[bundle[1]]={true, table.unpack(ret,2)} end end if status == "error" or coroutine.status(kernelCoro) == "dead" then @@ -556,6 +574,12 @@ local ok, err = xpcall(function() end displaySuperBadError("Kernel error: " .. tostring(err)) coroutine.yield("key") + elseif status == "success" then + if EFI.reboot then + apis.os.reboot() + end + displaySuperBadError("Kernel error: Attempted to yield main thread\n"..debug.traceback(kernelCoro, "Attempted to yield main thread")) + coroutine.yield("key") end initFs:refresh() end diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/01_periph.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/01_periph.kmod index 99953dc..58a2006 100644 --- a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/01_periph.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/01_periph.kmod @@ -3,6 +3,7 @@ local kernel=... kernel.cct={} kernel.cct.peripheral={} +kernel.cct.callAsync=kernel.apis.callAsync local peripheral=kernel.cct.peripheral local apis = kernel.apis local native = apis.peripheral @@ -103,6 +104,40 @@ function peripheral.getName(peripheral) end function peripheral.call(name, method, ...) + if native.isPresent(name) then + local id = kernel.cct.callAsync(native.call, name, method, ...) + kernel.currentTask.io=function() + if kernel.apis.callAsyncReturn[id] then + local r=kernel.apis.callAsyncReturn[id] + if not r[1] then error(r[2]) end + kernel.apis.callAsyncReturn[id]=nil + return table.unpack(r,2) + end + end + kernel.currentTask.status="D" + return + end + + for n = 1, #sides do + local side = sides[n] + if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then + local id = kernel.cct.callAsync(native.call, side, "callRemote", name, method, ...) + kernel.currentTask.io=function() + if kernel.apis.callAsyncReturn[id] then + local r=kernel.apis.callAsyncReturn[id] + if not r[1] then error(r[2]) end + kernel.apis.callAsyncReturn[id]=nil + return table.unpack(r,2) + end + end + kernel.currentTask.status="D" + return + end + end + return nil +end + +function peripheral.callnative(name, method, ...) if native.isPresent(name) then return native.call(name, method, ...) end @@ -116,7 +151,7 @@ function peripheral.call(name, method, ...) return nil end -function peripheral.wrap(name) +function peripheral.wrap(name, wrap) local methods = peripheral.getMethods(name) if not methods then return nil @@ -130,9 +165,17 @@ function peripheral.wrap(name) type = types[1], types = types, }) - for _, method in ipairs(methods) do - result[method] = function(...) - return peripheral.call(name, method, ...) + if wrap then + for _, method in ipairs(methods) do + result[method] = function(...) + return peripheral.call(name, method, ...) + end + end + else + for _, method in ipairs(methods) do + result[method] = function(...) + return peripheral.callnative(name, method, ...) + end end end return result @@ -149,4 +192,4 @@ function peripheral.find(ty, filter) end end return table.unpack(results) -end \ No newline at end of file +end diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/13_devraw.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/13_devraw.kmod new file mode 100644 index 0000000..47795d3 --- /dev/null +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/13_devraw.kmod @@ -0,0 +1,26 @@ +--:Minify:-- +local kernel=... +local peripheral=kernel.cct.peripheral + +local function wrap(p) + return function(op, mode) + if op=="type" then + return "device" + elseif op=="open" then + if kernel.uid~=0 then error("EACCES") end + return peripheral.wrap(p, true) + end + end +end + +local peripherals=peripheral.getNames() +for i=1, #peripherals do + local p=peripherals[i] + local typ=peripheral.getType(p) + local file=wrap(p) + kernel.devfs.data["raw"][p]=file + local typefolder=kernel.devfs.data["raw"]["by-type"][typ] + if not typefolder then typefolder={} end + typefolder[tostring(#table.keys(typefolder)+1)] = file + kernel.devfs.data["raw"]["by-type"][typ]=typefolder +end \ No newline at end of file diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod index 0e1fa0e..c5d9432 100644 --- a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/22_http.kmod @@ -120,6 +120,7 @@ function handler.connect(fd, address) end fdo.socket.active=true fdo.socket.url=url + fdo.socket.loaded=false return true end @@ -129,10 +130,11 @@ function handler.connect(fd, address) return end - if not kernel.cct.httpqueue[fdo.socket.url] then + if not kernel.cct.httpqueue[fdo.socket.url] and not fdo.socket.loaded then fdo.socket.file=kernel.sfile(buildResponse(kernel.cct.httpresponse[fdo.socket.url])) kernel.cct.httpqueue[fdo.socket.url]=nil kernel.cct.httpresponse[fdo.socket.url]=nil + fdo.socket.loaded=true end if not fdo.socket.file then @@ -141,6 +143,7 @@ function handler.connect(fd, address) fdo.socket.file=kernel.sfile(buildResponse(kernel.cct.httpresponse[fdo.socket.url])) kernel.cct.httpqueue[fdo.socket.url]=nil kernel.cct.httpresponse[fdo.socket.url]=nil + fdo.socket.loaded=true return fdo.socket.file.read(count) end end @@ -156,10 +159,11 @@ function handler.connect(fd, address) return end - if not kernel.cct.httpqueue[fdo.socket.url] then + if not kernel.cct.httpqueue[fdo.socket.url] and not fdo.socket.loaded then fdo.socket.file=kernel.sfile(buildResponse(kernel.cct.httpresponse[fdo.socket.url])) kernel.cct.httpqueue[fdo.socket.url]=nil kernel.cct.httpresponse[fdo.socket.url]=nil + fdo.socket.loaded=true end if not fdo.socket.file then @@ -168,6 +172,7 @@ function handler.connect(fd, address) fdo.socket.file=kernel.sfile(buildResponse(kernel.cct.httpresponse[fdo.socket.url])) kernel.cct.httpqueue[fdo.socket.url]=nil kernel.cct.httpresponse[fdo.socket.url]=nil + fdo.socket.loaded=true return fdo.socket.file.seek(whence, offset) end end diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod index 58cbe04..e0f6a4f 100644 --- a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod @@ -144,7 +144,6 @@ local function write(text, term) term.setCursorPos(x, y) end -kernel.devfs.data.tty={} kernel.cct.ctrl,kernel.cct.alt = false, false local function serializeBool(bool) diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_deamon.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_daemon.kmod similarity index 88% rename from Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_deamon.kmod rename to Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_daemon.kmod index 0892e73..c5ef91c 100644 --- a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_deamon.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_daemon.kmod @@ -1,10 +1,11 @@ --:Minify:-- local kernel=... local keys=kernel.apis.keys +kernel.cct.eventhooks={} -kernel.processes.cctdeamon = function() +kernel.processes.cctdaemon = function() local timeout = false - kernel.log("CCT deamon started") + kernel.log("CCT daemon started") while true do local event = {kernel.EFI:getMachineEvent()} @@ -84,6 +85,13 @@ kernel.processes.cctdeamon = function() kernel.cct.httperror[event[2]]=event[3] kernel.cct.httpresponse[event[2]]=event[4] end + else + if kernel.cct.eventhooks[eventType] then + local ok,err = xpcall(kernel.cct.eventhooks[eventType], debug.traceback, table.unpack(event)) + if not ok then + kernel.log("Error on eventhook "..eventType.."\n"..err) + end + end end timeout = false @@ -97,4 +105,4 @@ kernel.processes.cctdeamon = function() end end -kernel.log("CCT deamon queued for execution") \ No newline at end of file +kernel.log("CCT daemon queued for execution") \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/boot/kernel.lua b/Src/Hyperion-kernel/data/boot/kernel.lua index de11879..0c049db 100644 --- a/Src/Hyperion-kernel/data/boot/kernel.lua +++ b/Src/Hyperion-kernel/data/boot/kernel.lua @@ -1,5 +1,6 @@ --:Minify:-- local EFI=... +--pf EFI.beep(440, 500) local screen=EFI.screenCtl local ifs=EFI.initfs @@ -302,20 +303,24 @@ for _, i in ipairs(ifs.list("/lib/modules")) do for _,v in ipairs(modlist) do local prior=tonumber(v:sub(1,2)) if prior then - modules[prior+1][#modules[prior+1]+1]="/lib/modules/"..i.."/"..v + modules[prior+1][#modules[prior+1]+1]=i.."/"..v end end end end kernel.ifs=ifs +--pf kernel.apis=EFI.firmware +--pf kernel.EFI=EFI kernel.arch=arch kernel.initdisks=disks kernel.screen=screen kernel.processes={} kernel.fstab=fstab +kernel.denied={} +kernel.loadingModule="kernel" kernel.kernelTask = { name="kernel", @@ -357,6 +362,11 @@ function kernel.asyncReturn(...) kernel.currentTask.syscallReturn = {...} end +function kernel.deny(moduleid) + kernel.denied[moduleid]=true + if kernel.config.showModLoad then kernel.log("Module "..kernel.loadingModule.." denied "..moduleid, "DBUG", 0xFF0000) end +end + kernel.syscalls["time"]=function() return kernel.EFI:getEpochMs() end kernel.syscalls["date"]=function() return kernel.EFI:date() end kernel.syscalls["log"]=kernel.log @@ -390,28 +400,39 @@ kernel.syscalls["halt"]=function() kernel.halt() end end +kernel.syscalls["saveLog"]=function() + if kernel.uid==0 or kernel.groups.wheel then + kernel.saveLog() + end +end kernel.saveLog() kernel.log("Running modules") for _,p in ipairs(modules) do for _,v in ipairs(p) do - if kernel.config.showModLoad then kernel.log("Loading module "..v, "DBUG", 0x00FFFF) end - local code=ifs.readAllText(v) - if not code then - kernel.panic("Failed to read module "..v) + kernel.loadingModule=v + if not kernel.denied[v] then + if kernel.config.showModLoad then kernel.log("Loading module "..v, "DBUG", 0x00FFFF) end + local code=ifs.readAllText("/lib/modules/"..v) + if not code then + kernel.panic("Failed to read module "..v) + end + local func,err=load(code,"@"..v) + if not func then kernel.panic("ModuLoadErr: "..tostring(err)) end + local status, err = xpcall(func,debug.traceback, kernel) + if not status then kernel.panic("ModuRunErr: "..tostring(err)) end + if kernel.config.showModLoad then kernel.log("Loaded module "..v, "DBUG", 0x00FFFF) end + if kernel.config.moreLogsaves then kernel.saveLog() end + else + if kernel.config.showModLoad then kernel.log("Denied module "..v, "DBUG", 0xFF0000) end end - local func,err=load(code,"@"..v) - if not func then kernel.panic("ModuLoadErr: "..tostring(err)) end - local status, err = xpcall(func,debug.traceback, kernel) - if not status then kernel.panic("ModuRunErr: "..tostring(err)) end - if kernel.config.showModLoad then kernel.log("Loaded module "..v, "DBUG", 0x00FFFF) end - if kernel.config.moreLogsaves then kernel.saveLog() end end end kernel.log("Kernel initialized successfully.") kernel.saveLog() kernel.status="running" +kernel.loadingModule=nil screen:disable() local ok,err = xpcall(kernel.main, debug.traceback) if not ok then diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod index decbf4e..6a3c558 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod @@ -690,7 +690,9 @@ function vfs.open(path, mode) local handle if disk:type(diskPath) ~= "directory" then handle = disk:open(diskPath, mode) - if type(handle) ~= "table" then error("ENFILE") end + if type(handle, true) ~= "table" then + error("ENFILE") + end end if isNew then @@ -761,7 +763,7 @@ function vfs.close(fd) local task = kernel.currentTask local file = task.fd[fd] if not file then error("EBADF") end - if not task.fd[fd].isvirt then + if not task.fd[fd].isvirt then total = total - 1 end task.fd[fd] = nil @@ -1147,6 +1149,12 @@ function vfs.devctl(fd, method, ...) return kernel.currentTask.fd[fd].handle[method](...) end +function vfs.devlst(fd) + if not kernel.currentTask.fd[fd] then error("EBADF") end + if not kernel.currentTask.fd[fd] then error("EINVAL") end + return table.keys(kernel.currentTask.fd[fd].handle) +end + vfs.resolveMount = resolveMount local sys = kernel.syscalls @@ -1179,6 +1187,7 @@ sys["chroot"] = vfs.chroot sys["dup"] = vfs.dup sys["dup2"] = vfs.dup2 sys["devctl"] = vfs.devctl +sys["devlst"] = vfs.devlst sys["symlink"] = vfs.symlink sys["readlink"] = vfs.readlink sys["access"] = vfs.access diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod index 0a01ce5..cd147a6 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_devfs.kmod @@ -214,6 +214,8 @@ end data[".meta"]=strFile(buildMeta({ stdin="/proc/self/fd/0", stdout="/proc/self/fd/1", + stderr="/proc/self/2", + fd="/proc/self/fd", log="/var/log/syslog.log" })) @@ -222,6 +224,7 @@ if kernel.EFI.getEEPROM then if op=="type" then return "character device" elseif op=="open" then + if kernel.uid~=0 then error("EACCES") end if mode=="r" then local ptr,eeprom=1,kernel.EFI:getEEPROM() return { @@ -231,7 +234,6 @@ if kernel.EFI.getEEPROM then end } elseif mode=="w" then - if kernel.uid~=0 then error("EACCES") end local firstwrite=true return { write=function(data) @@ -243,7 +245,6 @@ if kernel.EFI.getEEPROM then end } elseif mode=="a" then - if kernel.uid~=0 then error("EACCES") end return { write=function(data) kernel.EFI:setEEPROM(kernel.EFI:getEEPROM()..data) @@ -260,6 +261,7 @@ if kernel.EFI.getNvram then if op=="type" then return "character device" elseif op=="open" then + if kernel.uid~=0 then error("EACCES") end if mode=="r" then local ptr,nvram=1,kernel.EFI:getNvram() return { @@ -269,7 +271,6 @@ if kernel.EFI.getNvram then end } elseif mode=="w" then - if kernel.uid~=0 then error("EACCES") end local firstwrite=true return { write=function(data) @@ -281,7 +282,6 @@ if kernel.EFI.getNvram then end } elseif mode=="a" then - if kernel.uid~=0 then error("EACCES") end return { write=function(data) kernel.EFI:setNvram(kernel.EFI:getNvram()..data) @@ -294,7 +294,15 @@ if kernel.EFI.getNvram then end data["disk"]={["by-id"]={}, ["by-path"]={}, ["by-label"]={}} +-- disks +for i,v in pairs(kernel.vfs.mounts) do + +end + +data["raw"]={["by-type"]={}} +data["gfx"]={} data["input"]={} +data["tty"]={} kernel.devfs={} kernel.devfs.data=data kernel.devfs.proxy=proxy diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod index 12cbe09..9ab0178 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod @@ -150,7 +150,6 @@ function sys.exec(path, args, envars) tasks[tostring(task.pid)].status = "Z" end) task.syscallReturn = {} - coroutine.yield() end function sys.sleep(s) diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/47_dbg.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/48_dbg.kmod similarity index 100% rename from Src/Hyperion-kernel/data/lib/modules/hyperion/47_dbg.kmod rename to Src/Hyperion-kernel/data/lib/modules/hyperion/48_dbg.kmod diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/90_kgc.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/90_kgc.kmod index 9a14d1a..9ad2300 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/90_kgc.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/90_kgc.kmod @@ -1,3 +1,4 @@ +--:Minify:-- local kernel = ... kernel.processes.kgc = function() while true do @@ -6,6 +7,6 @@ kernel.processes.kgc = function() kernel.reqcache[i] = nil end end - kernel.sleep(5000) + sleep(5) end end \ No newline at end of file diff --git a/Src/gfxterm/data/lib/gfx b/Src/gfxterm/data/lib/gfx new file mode 100644 index 0000000..0176b7b --- /dev/null +++ b/Src/gfxterm/data/lib/gfx @@ -0,0 +1,84 @@ +--:Minify:-- +local lib = {} + +--[[ +Example framebuffer object + +fb = { + r={ + "","" -- repeat for # of rows length of string is the # of collums + }, + g = { + "","" + }, + b = { + "","" + } +} + +Example font object + +font = { + width=int, + hight=int, + data={ + A={ + "Ga","gs","Gk" -- length of string is byte alligned with the string being a binary bitmap + } + } +} +]] + +function lib.newFbObj(fb) + local handle = {} + + function handle.setPixel(x,y,color24) + + end + + function handle.line(x1,y1,x2,y2,color24) + + end + + function handle.box(x1,y1,x2,y2,color24) + + end + + function handle.filledBox(x1,y1,x2,y2,color24) + + end + + function handle.tri(x1,y1,x2,y2,x3,y3,color24) + + end + + function handle.filledTri(x1,y1,x2,y2,x3,y3,color24) + + end + + function handle.window(id,x,y,w,h,writeonly) + + end + + function handle.editWindow(id,x,y,w,h) + + end + + function handle.text(x,y,font,color24) + + end + + function handle.draw() + + end + + function handle.getPixel(x,y) + + end + + function handle.getPixels(x1y1,x2,y2) + + end + + return handle +end \ No newline at end of file diff --git a/Src/gfxterm/data/lib/psf b/Src/gfxterm/data/lib/psf new file mode 100644 index 0000000..f732e15 --- /dev/null +++ b/Src/gfxterm/data/lib/psf @@ -0,0 +1,232 @@ +-- psf.lua +-- NeetComputers PSF1 & PSF2 font renderer + +-- Copyright 2026 SpartanSoftware +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +-- MODULE API +-- psf.open(path, disk = 0) Returns a Font object, or nil + errmsg +-- +-- FONT OBJECT API +-- font:print(x, y, text) Draw text in white +-- font:print(x, y, text, r, g, b) Draw text in given color +-- font:measure(text) Width of string in pixels +-- font:lineHeight() Font height in pixels +-- font:setSpacing(w) Set px width of glyph spacing +-- font:close() Free all layers + +local psf = {} + +local function readUInt(header, n) + local bytes = header.read(n) + if not bytes or #bytes < n then return nil end + local value = 0 + for i = 1, n do + value = value + string.byte(bytes, i) * (256 ^ (i - 1)) + end + return math.floor(value) +end + +local function parseGlyph(bytes, w, h) + local bytesPerRow = math.floor((w + 7) / 8) + local pixels = {} + for y = 1, h do + pixels[y] = {} + for x = 1, w do + local byteIdx = (y - 1) * bytesPerRow + math.floor((x - 1) / 8) + 1 + local bitPos = 7 - ((x - 1) % 8) + local b = string.byte(bytes, byteIdx) or 0 + pixels[y][x] = (math.floor(b / (2 ^ bitPos)) % 2 == 1) + end + end + return pixels +end + +local OFF_PIXEL = "\0\0\0\0" + +local function getGlyphBuffer(glyph, r, g, b) + local cache = glyph._bufCache + if not cache then + cache = {} + glyph._bufCache = cache + end + + local key = r * 65536 + g * 256 + b + local buf = cache[key] + if buf then return buf end + + local onPixel = string.char(r, g, b, 255) + local pixels = glyph.pixels + local chunks = {} + local n = 0 + + for y = 1, glyph.height do + local row = pixels[y] + for x = 1, glyph.width do + n = n + 1 + chunks[n] = row[x] and onPixel or OFF_PIXEL + end + end + + buf = table.concat(chunks) + cache[key] = buf + return buf +end + +local function parsePSF1(header, glyphs) + local mode = readUInt(header, 1) + local charsize = readUInt(header, 1) + if not charsize then return false, "truncated PSF1 header" end + + local count = (mode and (mode % 4 >= 2)) and 512 or 256 + for i = 0, count - 1 do + local raw = header.read(charsize) + if not raw or #raw < charsize then break end + glyphs[i] = { width = 8, height = charsize, + pixels = parseGlyph(raw, 8, charsize) } + end + return true, 8, charsize +end + +local function parsePSF2(header, glyphs) + readUInt(header, 4) + local headersize = readUInt(header, 4) + readUInt(header, 4) + local numglyph = readUInt(header, 4) + local bytesperglyph = readUInt(header, 4) + local h = readUInt(header, 4) + local w = readUInt(header, 4) + if not w or not h then return false, "truncated PSF2 header" end + + local consumed = 32 + if headersize > consumed then + header.seek('cur', headersize - consumed) + end + + for i = 0, numglyph - 1 do + local raw = header.read(bytesperglyph) + if not raw or #raw < bytesperglyph then break end + glyphs[i] = { width = w, height = h, + pixels = parseGlyph(raw, w, h) } + end + return true, w, h +end + +local Font = {} +Font.__index = Font + +function Font:print(x, y, text, r, g, b) + assert(not self._closed, "psf: font has been closed") + + r = r or 255 + g = g or 255 + b = b or 255 + + local sw = screen.getSize() + local cur = x + local spacing = self._spacing + + for i = 1, #text do + if cur >= sw then break end + local code = string.byte(text, i) + local glyph = self._glyphs[code] + if glyph then + local buf = getGlyphBuffer(glyph, r, g, b) + screen.drawPixels(cur, y, buf, glyph.width, glyph.height) + cur = cur + glyph.width + spacing + end + end +end + +function Font:measure(text) + local w = 0 + local count = 0 + for i = 1, #text do + local g = self._glyphs[string.byte(text, i)] + if g then + w = w + g.width + count = count + 1 + end + end + if count > 1 then + w = w + self._spacing * (count - 1) + end + return w +end + +function Font:lineHeight() + return self._height +end + +function Font:close() + if self._closed then return end + for _, glyph in pairs(self._glyphs) do + glyph._bufCache = nil + end + self._glyphs = {} + self._closed = true +end + +function Font:setSpacing(px) + self._spacing = px +end + +function psf.open(path, disk) + disk = disk or 0 + + if not files.exists(path, disk) then + return nil, "file not found: " .. path + end + + local ok, header = pcall(files.open, path, 'rb', disk) + if not ok or not header then + return nil, "could not open: " .. path + end + + local magic = header.read(2) + if not magic or #magic < 2 then + header.close() + return nil, "could not read magic bytes" + end + + local b1, b2 = string.byte(magic, 1), string.byte(magic, 2) + local glyphs = {} + local ok, w, h + + if b1 == 0x36 and b2 == 0x04 then + ok, w, h = parsePSF1(header, glyphs) + elseif b1 == 0x72 and b2 == 0xb5 then + header.read(2) + ok, w, h = parsePSF2(header, glyphs) + else + header.close() + return nil, string.format("not a PSF file (magic: %02x %02x)", b1, b2) + end + + header.close() + + if not ok then + return nil, w + end + + return setmetatable({ + _glyphs = glyphs, + _width = w, + _height = h, + _spacing = 0, + _closed = false, + }, Font) +end + +return psf diff --git a/Src/gfxterm/test/usr/local/gfxterm/tests/uv.lsl b/Src/gfxterm/test/usr/local/gfxterm/tests/uv.lsl new file mode 100644 index 0000000..e69de29 diff --git a/Src/hysh/data/bin/hysh b/Src/hysh/data/bin/hysh index 9afded8..3e178f9 100644 --- a/Src/hysh/data/bin/hysh +++ b/Src/hysh/data/bin/hysh @@ -833,14 +833,18 @@ builtinCmds.ops = function() end end -builtinCmds.reboot = function () +builtinCmds.reboot = function() syscall.reboot() end -builtinCmds.shutdown = function () +builtinCmds.shutdown = function() syscall.shutdown() end +builtinCmds.kill = function(id) + syscall.kill(tonumber(id)) +end + local function listDir(dir, prefix) local ok, entries = pcall(syscall.listdir, dir) if not ok or not entries then return {} end diff --git a/Src/hysh/data/bin/redirect b/Src/hysh/data/bin/redirect new file mode 100644 index 0000000..894b8a3 --- /dev/null +++ b/Src/hysh/data/bin/redirect @@ -0,0 +1,14 @@ +--:Minify:-- +local args = {...} +local list = syscall.listdir("/proc/self/fd") +for i=1, #list do + syscall.close(tonumber(list[i])) +end + +if #args>=2 then + for i=2, #args do + syscall.open(args[i], "rw") + end +end + +syscall.exec(args[1]) \ No newline at end of file diff --git a/Src/minify/data/lib/minify b/Src/minify/data/lib/minify index 1b7d0c6..faf7d7b 100644 --- a/Src/minify/data/lib/minify +++ b/Src/minify/data/lib/minify @@ -1,3 +1,4 @@ +--:Minify:-- --[[ MIT License @@ -89,7 +90,11 @@ local WhiteChars = lookupify { ' ', '\n', '\t', '\r' } local EscapeForCharacter = { ['\r'] = '\\r', ['\n'] = '\\n', ['\t'] = '\\t', ['"'] = '\\"', ["'"] = "\\'", ['\\'] = '\\' } -local CharacterForEscape = { ['r'] = '\r', ['n'] = '\n', ['t'] = '\t', ['"'] = '"', ["'"] = "'", ['\\'] = '\\' } +local CharacterForEscape = { ['r'] = '\r', ['n'] = '\n', ['t'] = '\t', ['"'] = '"', ["'"] = "'", ['\\'] = '\\', ['b'] = '\b', ['f'] = '\f' } + +for i=0,255 do + CharacterForEscape[tostring(i)]=string.char(i) +end local AllIdentStartChars = lookupify { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', @@ -201,9 +206,9 @@ local function CreateLuaTokenStream(text) end q = q + 1 end - for _, token in pairs(tokenBuffer) do - print(token.Type .. "<" .. token.Source .. ">") - end + --for _, token in pairs(tokenBuffer) do + -- print(token.Type .. "<" .. token.Source .. ">") + --end olderr("file<" .. line .. ":" .. char .. ">: " .. str) end @@ -485,9 +490,9 @@ local function CreateLuaParser(text) if tk.Type == type and (source == nil or tk.Source == source) then return get() else - for i = -3, 3 do - print("Tokens[" .. i .. "] = `" .. peek(i).Source .. "`") - end + --for i = -3, 3 do + -- print("Tokens[" .. i .. "] = `" .. peek(i).Source .. "`") + --end if source then error(getTokenStartPosition(tk) .. ": `" .. source .. "` expected.") else @@ -666,7 +671,7 @@ local function CreateLuaParser(text) get() return body, after else - print(after.Type, after.Source) + --print(after.Type, after.Source) error(getTokenStartPosition(after) .. ": " .. terminator .. " expected.") end end @@ -2802,6 +2807,7 @@ local function StripAst(ast) stript(sep) end end + stript(stat.Token_OpenParen) for index, arg in pairs(stat.ArgList) do stript(arg) @@ -3074,7 +3080,7 @@ end local function validateCode(code, validate) if validate then - local func,err = load(code, "@minifyvalidation", "t", {}) + local func,err = load(code, "@minifyvalidation", "t", _G) if not func then error(err) end diff --git a/Src/spm/data/bin/spm b/Src/spm/data/bin/spm index 1845e60..09e3b13 100644 --- a/Src/spm/data/bin/spm +++ b/Src/spm/data/bin/spm @@ -16,10 +16,11 @@ local spm = function(...) i = false, e = false, t = false, + s = false, sysroot = "", init = false, help = false, - source = false + overwrite = false } local i = 1 @@ -27,7 +28,9 @@ local spm = function(...) local http = require("http") local json = require("json") local tar = require("tar") + local minify = require("minify") local deflate = require("deflate") + local bit32 = require("bit32") local httpcache = {} local function get(url) @@ -93,6 +96,82 @@ local spm = function(...) i = i + 1 end + i=nil + + if cloptions.help or cloptions.h then + if cloptions.S then + print("spm -S - Synchronize Packages") + print("") + print("Usage:") + print(" spm -S [options] ") + print("") + print("Options:") + print(" -y Refresh package databases") + print(" -u Upgrade installed packages") + print(" -i Show remote package information") + print(" -s Download source") + print("") + print("Examples:") + print(" spm -Sy") + print(" spm -S package") + print(" spm -Syu") + return + + elseif cloptions.Q then + print("spm -Q - Query Package Database") + print("") + print("Usage:") + print(" spm -Q [options] [package]") + print("") + print("Options:") + print(" -i Show installed package information") + print(" -l List files owned by a package") + print(" -o Find which package owns a file") + print(" -e List explicitly installed packages") + print(" -t List orphan packages") + print("") + print("Examples:") + print(" spm -Q") + print(" spm -Qi lua") + print(" spm -Ql lua") + print(" spm -Qo /bin/lua") + return + + elseif cloptions.R then + print("spm -R - Remove Packages") + print("") + print("Usage:") + print(" spm -R [options] ") + print("") + print("Currently no remove-specific options are implemented.") + print("") + print("Example:") + print(" spm -R package") + return + + else + print("spm - HyperionOS Package Manager") + print("") + print("Usage:") + print(" spm [options] [targets]") + print("") + print("Operations:") + print(" -S Synchronize packages") + print(" -Q Query package database") + print(" -R Remove packages") + print("") + print("General Options:") + print(" -h, --help Show help") + print(" --init Initialize spm") + print(" --sysroot DIR Operate on alternate root") + print("") + print("For operation-specific help:") + print(" spm -Sh") + print(" spm -Qh") + print(" spm -Rh") + return + end + end if cloptions.sysroot=="" then syscall.chdir("/") @@ -113,6 +192,17 @@ local spm = function(...) print("spm not initialized run \"spm --init\"") return end + local log = fs.open("var/log/spm.log", "w") + + local function w(...) + local args = {...} + local output = "" + for i = 1, #args do output = output .. tostring(args[i]) .. "\t" end + output = output:sub(1, -2) + syscall.write(1, output.."\n") + log.write(output.."\n") + log.flush() + end local repodb = string.split(fs.readAllText("var/spm/db/repos.list"), "\n") local sourcelist = string.split(fs.readAllText("etc/spm/sources.list"), "\n") @@ -192,29 +282,29 @@ local spm = function(...) for _, url in ipairs(repodb) do local ok, repo = checkRepo(url) if not ok then - print("Failed to contact repository:") - print(url) - print("Consider running 'spm -Sy' to remove broken repositories.") + w("Failed to contact repository:") + w(url) + w("Consider running 'spm -Sy' to remove broken repositories.") else if repo.packages then if repo.packages[name] then local pkgurl = repo.packages[name] local resp = get(pkgurl) if not resp then - print("Repository: "..url) - print("Has broken package: "..name) - print("Ignoring") + w("Repository: "..url) + w("Has broken package: "..name) + w("Ignoring") else if resp.code ~= 200 then - print("Repository: "..url) - print("Has broken package: "..name) - print("Ignoring") + w("Repository: "..url) + w("Has broken package: "..name) + w("Ignoring") else local pkgjson = json.decode(resp.body) if not pkgjson then - print("Repository: "..url) - print("Has broken package: "..name) - print("Ignoring") + w("Repository: "..url) + w("Has broken package: "..name) + w("Ignoring") else return { url=pkgurl, @@ -236,14 +326,207 @@ local spm = function(...) return false, "target not found: "..name end + local function flatten(t) + local ret={} + for _,v in ipairs(t.content) do + if v.type == "dir" then + local f=flatten(v) + for i,c in pairs(f) do + ret[i]=c + end + elseif v.type == "file" then + ret[v.name]=v.content + end + end + return ret + end + + local function ptar(t, pkg) + t=t.content[1] + if t.name~=pkg.id then w("Tar contains "..t.name.." not "..pkg.id) return false end + local ret={} + for i=1, #t.content do + if t.content[i].name == "data" then + local data=flatten(t.content[i]) + local new={} + for p,v in pairs(data) do + new[p:sub(#pkg.id+7)]=v + end + ret.data=new + elseif t.content[i].name == "control" then + local data=flatten(t.content[i]) + local new={} + for p,v in pairs(data) do + new[p:sub(#pkg.id+10)]=v + end + ret.control=new + end + end + return ret + end + + local function mini(tabl) + local ret={} + for i,v in pairs(tabl) do + if v:sub(1,12)=="--:Minify:--" then + local ok, code = pcall(minify.minify,v) + if not ok then w("Failed to minify "..i..":\n"..code) ret[i]=v + else ret[i]=code end + else + ret[i]=v + end + end + return ret + end + + local function md5(msg) + local bit = bit32 + + local function rol(x, n) + return bit.lrotate(x, n) + end + + local function F(x, y, z) + return bit.bor(bit.band(x, y), bit.band(bit.bnot(x), z)) + end + + local function G(x, y, z) + return bit.bor(bit.band(x, z), bit.band(y, bit.bnot(z))) + end + + local function H(x, y, z) + return bit.bxor(x, y, z) + end + + local function I(x, y, z) + return bit.bxor(y, bit.bor(x, bit.bnot(z))) + end + + local function u32le(s, i) + return s:byte(i) + + s:byte(i + 1) * 0x100 + + s:byte(i + 2) * 0x10000 + + s:byte(i + 3) * 0x1000000 + end + + local function le32(x) + return string.char( + bit.band(x, 0xff), + bit.band(bit.rshift(x, 8), 0xff), + bit.band(bit.rshift(x, 16), 0xff), + bit.band(bit.rshift(x, 24), 0xff) + ) + end + + -- MD5 padding + local bitlen = #msg * 8 + + msg = msg .. "\128" + + while #msg % 64 ~= 56 do + msg = msg .. "\0" + end + + -- Append 64-bit little-endian length + local lo = bitlen % 0x100000000 + local hi = math.floor(bitlen / 0x100000000) + + msg = msg .. le32(lo) .. le32(hi) + + local a0 = 0x67452301 + local b0 = 0xefcdab89 + local c0 = 0x98badcfe + local d0 = 0x10325476 + + local S = { + 7,12,17,22, 7,12,17,22, 7,12,17,22, 7,12,17,22, + 5, 9,14,20, 5, 9,14,20, 5, 9,14,20, 5, 9,14,20, + 4,11,16,23, 4,11,16,23, 4,11,16,23, 4,11,16,23, + 6,10,15,21, 6,10,15,21, 6,10,15,21, 6,10,15,21 + } + + local K = { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + } + + for chunk = 1, #msg, 64 do + local M = {} + + for i = 0, 15 do + M[i] = u32le(msg, chunk + i * 4) + end + + local A = a0 + local B = b0 + local C = c0 + local D = d0 + + for i = 0, 63 do + local f + local g + + if i < 16 then + f = F(B, C, D) + g = i + elseif i < 32 then + f = G(B, C, D) + g = (5 * i + 1) % 16 + elseif i < 48 then + f = H(B, C, D) + g = (3 * i + 5) % 16 + else + f = I(B, C, D) + g = (7 * i) % 16 + end + + local tmp = D + D = C + C = B + + local x = A + f + K[i + 1] + M[g] + x = x % 0x100000000 + + B = (B + rol(x, S[i + 1])) % 0x100000000 + + A = tmp + end + + a0 = (a0 + A) % 0x100000000 + b0 = (b0 + B) % 0x100000000 + c0 = (c0 + C) % 0x100000000 + d0 = (d0 + D) % 0x100000000 + end + + local digest = le32(a0) .. le32(b0) .. le32(c0) .. le32(d0) + + return (digest:gsub(".", function(c) + return string.format("%02x", c:byte()) + end)) + end + if cloptions.S then if cloptions.y then - print("Updating repositories...") + w("Updating repositories...") repodb={} for _,v in ipairs(getRepos(sourcelist)) do repodb[#repodb+1]=v end - print("Writing new data...") + w("Writing new data...") local str = "" for _,v in ipairs(repodb) do str=str..v.."\n" @@ -257,7 +540,7 @@ local spm = function(...) local found = {} for i,v in ipairs(args) do local pkg, err = getPkg(v) - if not pkg then print(err) syscall.exit(1) end + if not pkg then w(err) syscall.exit(1) end needed[#needed+1] = pkg found[v]=true end @@ -286,10 +569,10 @@ local spm = function(...) if #needed==0 then syscall.exit() end - print("") - print("Packages("..tostring(#needed).."):") + w("") + w("Packages("..tostring(#needed).."):") printpkgs(needed) - print("") + w("") while true do local text = userinput(0, "Proceed with download [Y/n]", nil, 1) if text=="" then @@ -303,10 +586,131 @@ local spm = function(...) local files = {} for _,v in ipairs(needed) do - local file = http.get(v.tar) - + if not pkgdb[v.id] or not pkgdb[v.id].hash==v.hash then + w("Downloading "..v.id) + local resp = get(v.tar) + if not resp then + w("Package "..v.id.." failed GET") + syscall.exit() + end + if resp.code ~= 200 then + w("Package "..v.id.." returned code "..tostring(resp.code)) + syscall.exit() + end + local ok, repotar = pcall(tar.unpack, resp.body) + if not ok or not repotar then + w("Package "..v.id.." failed tar parsing") + syscall.exit() + end + local f=ptar(repotar, v) + if not f or not f.data then syscall.exit() end + if not cloptions.s then + f.data=mini(f.data) + end + f.hash=v.hash + files[v.id]=f + else + w("Package "..v.id.." hash already installed") + end end - + w("Checking for conflicts...") + local seen={} + for i,v in pairs(files) do + for f,c in pairs(v.data) do + if seen[f] then + w(i.." and "..seen[f].." have conflicting file "..f) + v.data[f]=nil + else + seen[f]=i + end + end + end + seen=nil + w("Checking for modified files...") + local block={} + for i, v in pairs(files) do + if pkgdb[i] then + if not cloptions.overwrite then + for f,h in pairs(v.data) do + if pkgdb[i].files[f]~=md5(fs.readAllText(f)) then + w(f.." was modified on disk, specify --overwrite to overwrite") + block[f]=true + end + end + end + else + if not cloptions.overwrite then + for f,h in pairs(v.data) do + if fs.exists(f) then + w(f.." already exists, specify --overwrite to overwrite or remove the file") + syscall.exit() + end + end + end + end + end + w("Adding delete calls...") + local delete={} + for i,v in pairs(files) do + if pkgdb[i] then + for f,c in pairs(pkgdb[i].files) do + if not v.data[f] then + if c~=md5(fs.readAllText(f)) then + w(f.." was modified on disk, specify --overwrite to overwrite") + else + delete[f]=true + end + end + end + end + end + w("Calculating useage...") + local net=0 + for i,v in pairs(files) do + for f,c in pairs(v.data) do + if not block[f] then + net=net+#c + end + end + for f,c in pairs(delete) do + net=net-#fs.readAllText(f) + end + end + w("") + w("Net Upgrade Size: "..tostring(net)) + w("") + while true do + local text = userinput(0, "Proceed with Installation [Y/n]", nil, 1) + if text=="" then + break + elseif text:lower()=="y" then + break + elseif text:lower()=="n" then + syscall.exit() + end + end + w("Updatating db...") + for i,v in pairs(files) do + local content={} + content.files={} + for f,c in pairs(v.data) do + content.files[f]=md5(c) + end + content.hash=v.hash + fs.writeAllText("var/spm/db/installed/"..i, json.encode(content)) + end + w("Writing changes...") + for i,v in pairs(files) do + w("Writing "..i) + for f,c in pairs(v.data) do + if not block[f] then + fs.writeAllText(f,c) + end + end + end + w("Install complete") + log.close() + elseif cloptions.R then -- remove tree elseif cloptions.Q then diff --git a/Src/spm/dependencies.txt b/Src/spm/dependencies.txt index 10ca011..5412049 100644 --- a/Src/spm/dependencies.txt +++ b/Src/spm/dependencies.txt @@ -1,4 +1,6 @@ tar deflate json -minify \ No newline at end of file +minify +bit32 +Hyperion-core \ No newline at end of file diff --git a/Src/tar/data/lib/tar b/Src/tar/data/lib/tar index 2876a2a..1f25ea3 100644 --- a/Src/tar/data/lib/tar +++ b/Src/tar/data/lib/tar @@ -1,3 +1,4 @@ +--:Minify:-- local LibDeflate = require("LibDeflate") local tar = {} diff --git a/bootstrap/cct-bootstrap.lua b/bootstrap/cct-bootstrap.lua new file mode 100644 index 0000000..271cb50 --- /dev/null +++ b/bootstrap/cct-bootstrap.lua @@ -0,0 +1,609 @@ +print("Running CC:Tweaked vm bootstrap") + +local bootloader=[=[ +---@diagnostic disable-next-line: undefined-global +local lterm = term +local function write(text, term) + local x, y = term.getCursorPos() + local w, h = term.getSize() + + for i = 1, #text do + local c = text:sub(i, i) + + if c == "\n" then + y = y + 1 + x = 1 + elseif c == "\t" then + local tabSize = 4 + local spaces = tabSize - ((x - 1) % tabSize) + term.write(string.rep(" ", spaces)) + x = x + spaces + elseif c == "\b" then + if x > 1 then + x = x - 1 + term.setCursorPos(x, y) + term.write(" ") + term.setCursorPos(x, y) + end + else + if x <= w and y <= h then + term.setCursorPos(x, y) + term.write(c) + x = x + 1 + end + end + + if x > w then + x = 1 + y = y + 1 + end + + if y - 1 >= h then + term.scroll(1) + y = h + term.setCursorPos(x, y) + end + end + + term.setCursorPos(x, y) +end + +local function displaySuperBadError(err) + lterm.setBackgroundColor(0x1) + lterm.setTextColor(0x4) + lterm.clear() + lterm.setCursorPos(1, 1) + lterm.write("A critical error occurred while loading the system:") + lterm.setCursorPos(1, 3) + write(err, lterm) + while true do end +end + +term.setCursorBlink(false) +local ok, err = xpcall(function() + --p + local apis = {BOOT_DRIVE_PATH = BOOT_DRIVE_PATH} + + local lua = { + coroutine = true, + debug = true, + _VERSION = true, + assert = true, + collectgarbage = true, + error = true, + gcinfo = true, + getmetatable = true, + ipairs = true, + __inext = true, + load = true, + math = true, + next = true, + pairs = true, + pcall = true, + rawequal = true, + rawget = true, + rawlen = true, + rawset = true, + select = true, + setmetatable = true, + string = true, + table = true, + tonumber = true, + tostring = true, + type = true, + xpcall = true, + _G = true + } + + local debug = debug + for i, v in pairs(_G) do + if not lua[i] or lua[i] == nil then + apis[i] = v + _G[i] = nil + end + end + --p + + local acekeys={ + [apis.keys.enter]="\n", + [apis.keys.tab]="\t", + [apis.keys.backspace]="\b", + [apis.keys.up]="\17", + [apis.keys.down]="\18", + [apis.keys.left]="\19", + [apis.keys.right]="\20", + } + + function sleep(time) + local stoptime = apis.os.clock() + (time) + while stoptime > apis.os.clock() do end + end + + apis.term.setPaletteColor(0x1, 0xFFFFFF) -- #000000 + apis.term.setPaletteColor(0x2, 0xFF0000) -- #FFFFFF + apis.term.setPaletteColor(0x4, 0x00FF00) -- #FF0000 + apis.term.setPaletteColor(0x8, 0x0000FF) -- #00FF00 + apis.term.setPaletteColor(0x10, 0x00FFFF) -- #0000FF + apis.term.setPaletteColor(0x20, 0xFF00FF) -- #00FFFF + apis.term.setPaletteColor(0x40, 0xFFFF00) -- #FF00FF + apis.term.setPaletteColor(0x80, 0xFF6D00) -- #FFFF00 + apis.term.setPaletteColor(0x100, 0x6DFF55) -- #FF6D00 + apis.term.setPaletteColor(0x200, 0x24FFFF) -- #6DFF55 + apis.term.setPaletteColor(0x400, 0x924900) -- #24FFFF + apis.term.setPaletteColor(0x800, 0x6D6D55) -- #924900 + apis.term.setPaletteColor(0x1000, 0xDBDBAA) -- #6D6D55 + apis.term.setPaletteColor(0x2000, 0x6D00FF) -- #DBDBAA + apis.term.setPaletteColor(0x4000, 0xB6FF00) -- #6D00FF + apis.term.setPaletteColor(0x8000, 0x000000) -- #B6FF00 + local eventQueue = {} + local function queueEvent(event, ...) + table.insert(eventQueue, {event, ...}) + end + + local colors = { + [0xFFFFFF]=0x0001, + [0x000000]=0x8000 + } + + local fg,bg=0x6D6D55,0x000000 + local l1f,l1d,l2,ops={},{},{},0 + + local function findClosest(tbl, target) + local closest = nil + local smallestDiff = math.huge + + for k, _ in pairs(tbl) do + if k==target then return k end + local diff = math.abs(k - target) + if diff < smallestDiff then + smallestDiff = diff + closest = k + end + end + + return closest + end + + local function aprox(c24) + ops = ops + 1 + + if ops % 1024 == 0 then + l1d = {} + l1f = {} + end + + if ops % 8192 == 0 then + l2 = {} + end + + if l2[c24] ~= nil then + return l2[c24] + end + + if l1d[c24] ~= nil then + l1f[c24] = l1f[c24] + 1 + + if l1f[c24] >= 16 then + l2[c24] = l1d[c24] + l1d[c24] = nil + l1f[c24] = nil + return l2[c24] + end + + return l1d[c24] + end + + local closestKey = findClosest(colors, c24) + if not closestKey then return nil end + + local value = colors[closestKey] + + l1d[c24] = value + l1f[c24] = 1 + + return value + end + --p + local p={} + local native = apis.peripheral + local sides = {"top", "bottom", "left", "right", "front", "back"} + + function p.getNames() + local results = {} + for n = 1, #sides do + local side = sides[n] + if native.isPresent(side) then + table.insert(results, side) + if native.hasType(side, "peripheral_hub") then + local remote = native.call(side, "getNamesRemote") + for _, name in ipairs(remote) do + table.insert(results, name) + end + end + end + end + return results + end + + function p.isPresent(name) + if native.isPresent(name) then + return true + end + + for n = 1, #sides do + local side = sides[n] + if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then + return true + end + end + return false + end + + function p.getType(peripheral) + if type(peripheral) == "string" then + if native.isPresent(peripheral) then + return native.getType(peripheral) + end + for n = 1, #sides do + local side = sides[n] + if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then + return native.call(side, "getTypeRemote", peripheral) + end + end + return nil + else + local mt = getmetatable(peripheral) + if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then + error("bad argument #1 (table is not a peripheral)", 2) + end + return table.unpack(mt.types) + end + end + + function p.hasType(peripheral, peripheral_type) + if type(peripheral) == "string" then + if native.isPresent(peripheral) then + return native.hasType(peripheral, peripheral_type) + end + for n = 1, #sides do + local side = sides[n] + if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then + return native.call(side, "hasTypeRemote", peripheral, peripheral_type) + end + end + return nil + else + local mt = getmetatable(peripheral) + if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then + error("bad argument #1 (table is not a peripheral)", 2) + end + return mt.types[peripheral_type] ~= nil + end + end + + function p.getMethods(name) + if native.isPresent(name) then + return native.getMethods(name) + end + for n = 1, #sides do + local side = sides[n] + if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then + return native.call(side, "getMethodsRemote", name) + end + end + return nil + end + + function p.getName(peripheral) + local mt = getmetatable(peripheral) + if not mt or mt.__name ~= "peripheral" or type(mt.name) ~= "string" then + error("bad argument #1 (table is not a peripheral)", 2) + end + return mt.name + end + + function p.call(name, method, ...) + if native.isPresent(name) then + return native.call(name, method, ...) + end + + for n = 1, #sides do + local side = sides[n] + if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then + return native.call(side, "callRemote", name, method, ...) + end + end + return nil + end + + function p.wrap(name) + local methods = p.getMethods(name) + if not methods then + return nil + end + + local types = { p.getType(name) } + for i = 1, #types do types[types[i]] = true end + local result = setmetatable({}, { + __name = "peripheral", + name = name, + type = types[1], + types = types, + }) + for _, method in ipairs(methods) do + result[method] = function(...) + return p.call(name, method, ...) + end + end + return result + end + + function p.find(ty, filter) + local results = {} + for _, name in ipairs(p.getNames()) do + if p.hasType(name, ty) then + local wrapped = p.wrap(name) + if filter == nil or filter(name, wrapped) then + table.insert(results, wrapped) + end + end + end + return table.unpack(results) + end + --p + local allscreens = {p.find("monitor")} + for i=1, #allscreens do + allscreens[i].setTextScale(.5) + allscreens[i].clear() + allscreens[i].setCursorPos(1,1) + end + + allscreens[#allscreens+1] = apis.term + + local EFI = { + getEpochMs = function() return apis.os.epoch("utc") end, + getUptime = function() return apis.os.clock() * 1000 end, + date = function() return apis.os.date("!%Y-%m-%dT%H:%M:%SZ", apis.os.epoch("utc") / 1000) end, + getMachineEvent = function() + if #eventQueue > 0 then + return table.unpack(table.remove(eventQueue, 1)) + else + return nil + end + end, + getEEPROM = function() return getFile(eeprom) end, + setEEPROM = function(_, text) + local h = apis.fs.open(eeprom, "w") + h.write(text) + h.close() + end, + initfs=fs, + disks=initFs, + screenCtl={ + print = function(_, text) + for i=1, #allscreens do + write(text.."\n", allscreens[i]) + end + end, + printInline = function(_, text) + for i=1, #allscreens do + write(text, allscreens[i]) + end + end, + clear = function() + for i=1, #allscreens do + allscreens[i].clear() + allscreens[i].setCursorPos(1, 1) + end + end, + resetCursor = function() + for i=1, #allscreens do + allscreens[i].setCursorPos(1, 1) + end + end, + setBackgroundColor = function(_, color) + bg=color + for i=1, #allscreens do + allscreens[i].setBackgroundColor(aprox(color)) + end + end, + setTextColor = function(_, color) + fg=color + for i=1, #allscreens do + allscreens[i].setTextColor(aprox(color)) + end + end, + getBackgroundColor = function() + return bg + end, + getTextColor = function() + return fg + end, + enable=function() + for i=1, #allscreens do + allscreens[i].clear() + allscreens[i].setCursorPos(1, 1) + end + end, + disable=function() end + }, + architecture="vm", + getNvram = function() return getFile("/nvram.dat") end, + setNvram = function(_, text) + local h = apis.fs.open("/nvram.dat", "w") + h.write(text) + h.close() + end, + firmware=apis, + reboot=false, + beep=function() end + } + + apis.term.setBackgroundColor(0x8000) + apis.term.setTextColor(0x1000) + apis.term.clear() + apis.term.setCursorPos(1, 1) + + local kernelCoro = coroutine.create(function() + --pf + ---@diagnostic disable-next-line: param-type-mismatch + local ok, err = xpcall(Kernel, debug.traceback, EFI) + if not ok and not EFI.reboot then displaySuperBadError(err) end + if err then + apis.os.reboot() + else + apis.os.shutdown() + end + end) + + function coroutine.resumeWithTimeout(co, timeout, ...) + local startTime = EFI.getEpochMs() + debug.sethook(co, function() + if EFI.getEpochMs() > startTime + timeout then + return coroutine.yield("timeout") + end + end, "", 1000) + local ret = {coroutine.resume(co, ...)} + if ret[1] and ret[2] == "timeout" then + return "timeout" + elseif ret[1] == false then + return "error", ret[2] + else + debug.sethook(co) + return "success", table.unpack(ret, 2) + end + end + + EFI.screenCtl:print("Loaded in " .. tostring(apis.os.clock()) .. " seconds.\n") + --p + + while true do + local status, err = coroutine.resumeWithTimeout(kernelCoro, 50) + apis.os.queueEvent("NoSleep") + local exit = false + while not exit do + local event = {coroutine.yield()} + if event[1] == "key" then + queueEvent(table.unpack(event)) + queueEvent("keyPressed", 1, event[2]) + if acekeys[event[2]] then + queueEvent("keyTyped", 1, acekeys[event[2]]) + end + elseif event[1] == "char" then + queueEvent(table.unpack(event)) + queueEvent("keyTyped", 1, event[2]) + elseif event[1] == "key_up" then + queueEvent(table.unpack(event)) + queueEvent("keyReleased", 1, event[2]) + elseif event[1] == "NoSleep" then + exit = true + else + queueEvent(table.unpack(event)) + end + end + if status == "error" or coroutine.status(kernelCoro) == "dead" then + if EFI.reboot then + apis.os.reboot() + end + displaySuperBadError("Kernel error: " .. tostring(err)) + coroutine.yield("key") + elseif status == "success" then + if EFI.reboot then + apis.os.reboot() + end + displaySuperBadError("Kernel error: Attempted to yield main thread") + coroutine.yield("key") + end + initFs:refresh() + end +end, debug.traceback) + +if not ok then displaySuperBadError("Fatal error during boot: " .. err) end +while true do coroutine.yield("key") end +]=] + +local args = {} +local keptAPIs = {keys=true, bit32 = true, bit = true, ccemux = true, config = true, coroutine = true, debug = true, fs = true, http = true, mounter = true, os = true, periphemu = true, peripheral = true, redstone = true, rs = true, term = true, utf8 = true, _HOST = true, _CC_DEFAULT_SETTINGS = true, _CC_DISABLE_LUA51_FEATURES = true, _VERSION = true, assert = true, collectgarbage = true, error = true, gcinfo = true, getfenv = true, getmetatable = true, ipairs = true, __inext = true,load = true, loadstring = true, math = true, newproxy = true, next = true, pairs = true, pcall = true, rawequal = true, rawget = true, rawlen = true, rawset = true, select = true, setfenv = true, setmetatable = true, string = true, table = true, tonumber = true, tostring = true, type = true, unpack = true, xpcall = true, turtle = true, pocket = true, commands = true, _G = true} +local t = {} +for k in pairs(_G) do if not keptAPIs[k] then table.insert(t, k) end end +for _,k in ipairs(t) do _G[k] = nil end +local native = _G.term.native() +for _, method in ipairs {"nativePaletteColor", "nativePaletteColour", "screenshot"} do native[method] = _G.term[method] end +_G.term = native +if _G.http then + _G.http.checkURL = _G.http.checkURLAsync + _G.http.websocket = _G.http.websocketAsync +end +if _G.commands then _G.commands = _G.commands.native end +if _G.turtle then _G.turtle.native, _G.turtle.craft = nil end +local delete = {os = {"version", "pullEventRaw", "pullEvent", "run", "loadAPI", "unloadAPI", "sleep"}, http = _G.http and {"get", "post", "put", "delete", "patch", "options", "head", "trace", "listen", "checkURLAsync", "websocketAsync"}, fs = {"complete", "isDriveRoot"}} +for k,v in pairs(delete) do for _,a in ipairs(v) do _G[k][a] = nil end end +local olderror = error +_G.error = function() end +_G.term.redirect = function() end +function _G.term.native() + _G.term.native = nil + _G.term.redirect = nil + _G.error = olderror + term.setBackgroundColor(32768) + term.setTextColor(1) + term.setCursorPos(1, 1) + term.setCursorBlink(true) + term.clear() + local file = bootloader + if file == nil then + term.setCursorBlink(false) + term.setTextColor(16384) + term.write("Could not find /boot/cct/boot.lua. UnBIOS cannot continue.") + term.setCursorPos(1, 2) + term.write("Press any key to continue") + coroutine.yield("key") + os.shutdown() + end + local fn, err = loadstring(file.readAll(), "@bootloader") + file.close() + if fn == nil then + term.setCursorBlink(false) + term.setTextColor(16384) + term.write("Could not load /boot/cc/boot.lua. UnBIOS cannot continue.") + term.setCursorPos(1, 2) + term.write(err) + term.setCursorPos(1, 3) + term.write("Press any key to continue") + coroutine.yield("key") + os.shutdown() + end + setfenv(fn, _G) + local oldshutdown = os.shutdown + os.shutdown = function() + os.shutdown = oldshutdown + return fn() + end +end +if debug then + local function restoreValue(tab, idx, name, hint) + local i, key, value = 1, debug.getupvalue(tab[idx], hint) + while key ~= name and key ~= nil do + key, value = debug.getupvalue(tab[idx], i) + i=i+1 + end + tab[idx] = value or tab[idx] + end + restoreValue(_G, "loadstring", "nativeloadstring", 1) + restoreValue(_G, "load", "nativeload", 5) + if http then restoreValue(http, "request", "nativeHTTPRequest", 3) end + restoreValue(os, "shutdown", "nativeShutdown", 1) + restoreValue(os, "reboot", "nativeReboot", 1) + if turtle then + restoreValue(turtle, "equipLeft", "v", 1) + restoreValue(turtle, "equipRight", "v", 1) + end + do + local i, key, value = 1, debug.getupvalue(peripheral.isPresent, 2) + while key ~= "native" and key ~= nil do + key, value = debug.getupvalue(peripheral.isPresent, i) + i=i+1 + end + _G.peripheral = value or peripheral + end +end \ No newline at end of file diff --git a/compile.py b/compile.py index 8287e38..5e9c75c 100644 --- a/compile.py +++ b/compile.py @@ -28,7 +28,7 @@ def debug(message): def sha256(path): - hasher = hashlib.sha256() + hasher = hashlib.md5() with open(path, "rb") as file: while chunk := file.read(1024 * 1024): diff --git a/install.lua b/install.lua new file mode 100644 index 0000000..c06c682 --- /dev/null +++ b/install.lua @@ -0,0 +1,15 @@ +local args={...} +local bootstrap="" +if args[1]=="cct" then + print("installing cct") + local function get(url) + local resp=http.get(url) + return resp.readAll() + end + bootstrap=get("https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/bootstrap/cct-bootstrap.lua") +else + error("Unsupported architecture") +end + +local func=load(bootstrap,"@Bootstrap", "t", _G) +func() \ No newline at end of file diff --git a/out b/out new file mode 100644 index 0000000000000000000000000000000000000000..f7d6e4dbbf43e9ab4b9b0f2f679b59f98519bf4f GIT binary patch literal 3904 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%0A(|G(?|{Ns9VeYdxn_T4^Xx%u~x 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 S#({G7|IBOBjFT8D7#ILRpGU3$ literal 2726 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 M-F4!-7%CVT0K9>X7ytkO diff --git a/packages/raw/Hyperion-firmware-ac.tar.gz b/packages/raw/Hyperion-firmware-ac.tar.gz index 7754c5db7823688b5a6622177602553fcef09bb6..5fbf01ce36e0cbe7715e3e2b7809d4abadb7485c 100644 GIT binary patch literal 3117 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 literal 3179 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 O+&5|#US_CZU;qH$23mLk diff --git a/packages/raw/Hyperion-firmware-addon-cct.tar.gz b/packages/raw/Hyperion-firmware-addon-cct.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..cf1c81c2dd46db8165a3a0822dfab4082af819a7 GIT binary patch literal 473 zcmb2|=HPJKR-eW6-=nf1wJ0+`Pd6>ID7QSZC{;HxB_%&kH#xaPuOzXE;q49I>}CTA z_JZ?uTrXGJN_S*^>~F`Z~fD>Whslclumn4+ZSt?_9l1lZS@&KNtV*9+tGkvb>W0!M> z|1laZZY*=&9HphpJtZyFNN(%X*BL!({o8WoWx~o=Wlb-gYi{2D{MpB#R~K`qtXsXq lRN2BTf6k4*&b6ypR&h2uC{U1EV9;P-006(B@jn0n literal 0 HcmV?d00001 diff --git a/packages/raw/Hyperion-firmware-ccpc.tar.gz b/packages/raw/Hyperion-firmware-ccpc.tar.gz index cc8fcb16263e2f7dc041022312b9dbf099515fe1..31e2ae19bfd8e1b1bc900366b9f25dabf80be29c 100644 GIT binary patch literal 7171 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 WSHZQb&X<4wS#R@sVk*N41_l7*eKfoP literal 8960 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 AE&u=k diff --git a/packages/raw/Hyperion-firmware-cct.tar.gz b/packages/raw/Hyperion-firmware-cct.tar.gz index dd2817f24451665d5ac961e06c74f2204ad58e18..ec917489e8f04ae4461c2f5922fb84d09e123a0e 100644 GIT binary patch literal 12190 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ξS#}Us3$(crul-YF_Yurhwb^TmOci z{FiO*w}0FJeKEiLT^?VEe|#kS`1X&=J^zJ%ufO_g+vaccjTt!Cyxs5rQTVQ3d4XS( z>X|z#Hk^AibLJQ}@0U~l`X~PU|M**f?!T44_8GJ&Jbto4)tsICFa5dyO7nC5{sBeOes`>Vu&|F7czuCD*O{@>O8zrx|1zboti%YUB{c$Fc8kpTc{g7(J% literal 11536 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 NY3+i>HUe-_60{wyl05yIj3*{%s3^uaWzmjp za`RGxR5g!xFZ#cCiD;ImVQA!%Puo0+jK6g-)PSC z`~K~x`$ebvdIAI|(Y0%S{8#+np8Ie9f*T*~Um5>nKlT6j zzjhCaWsU!u|H)tYFEKy)!vBS@>K#oa<<0-q%bWlAF6c@4XD;)vfA=4GrvKj${ePMG zZ@yo{zxK2Li=8VTFFyMJ@sImGM35OW3xvZC25WJ-N z@u@ATFBK-;xp3a}Wy7*vxht0J;axdx`l4-jqXM?;Ua8GpxTQYj&fBBwCX4NfJHIlg zvHg_PyMl(??Tl&SGi^WatBNze;&C+O+tbzC4gQ`vXJ+@<*LmI?7UDG zQkOEn=J5@gRLS(E>%*tK-&3~u^qsSDH}5EJ=C00@nf>ty_xV4J=l|dPDZl2wUG%^5 ziofFSnoH^@{J;69|B_eN*Wmhd{|(rXuOGn8%>OP$zV8k()O z`ER57ZjN^c-p7QhP1&2qr}IiTYhJeToSN4<7Ei5qOk856=&HCfX!-V?({!_grcBj1 z!#nG^>ACF>6zdKDA6KzAE8Q@|S3WJhclTMvStjqFZ2J?dmbg~)$HtvsG;fE0OsOvu zV>$S8?rpv2i*`-BQ@-lR54V`hwY_=rFU7V-9{axk_w6@wIiLG$KQaH}e{HXy^p}0P zMH36dm-}-J&V6zEdy4DA;rIWKt^4PGOuq5o_wD~SZwM~pV4Ly3`Cs$D_xt|4eE9pk z;p_ZWF`G`Eo7DG__d@e8dH1(}|BD>_=dZu*{kOXgEx%SRs@d(StrTu%6PdVWp0c7@uPC%YN8 zR^)UCNYvgcw{c^c+_`@?Ps1*wnA@lQk8v7(Hdnjf!Lm8h<*eu|6UwC-= z^RxfgNB$3N%3XLM=ihO|HUAy{JN}RN`7h~seZl|5*Z#K#rB!YF^WW@m`V~EK$NwN0 z@9{s~g6S{&U;ERC7vx{7Zz^yB2|NB@_>XZ-s0dT;mne184je}CWg z%bi^9m2r7-P^gHKsrEYYnydSJE=0YQ+w4`mGo;pQ#?lG5lk=2&=5Fs^RDW#Glb!2+ z{hf0=fBWn2D+6p^3rgo*vwgJWuIk27yrcl3IAL#e5vgF46PQMWvdpi@Y+#m zy~ywQqN*I7HzMa!|Le_TlT>|u*6D@vr{dhTWnVh(zGOI)FZBK3?+2A{LmsEbslKsL(63=EzAJL>e-t*WP@QopgheR}JG?a!SRTYp>^vtL(IFh^VdS$OV_)r$4EjNT{R z{}Ui=>_f0-!Xyf9t1uwfFzE{=1jF|1YR&n0fENvc#Wy Zjs*ID7QSZC{?#CSFa?oh~e#JTfQa-fwqThZCS+` zzD-|hxN*rBE|qnhtVv-Zd-h6jYj0r^uAQHzW<1&FYii}R{B2(YTC2nt&1kKewJJ#J z_bd5g)vcG5B#$tiTfVRFarMXfB{R3wUT)j^DOJ%oQe*neL(%D{rXD!II`6o^>~|C1 z&At)$TH=!T?DG@q-~TQ7cRbEAch073FF*RtJXASxhw5kf-RtVhzi09@Ac2~LvPK7=r`B$Zx|{b;_VVque!KsgzyFm#|3Ut|G)Jbh|KG0v zdHv=$wMY}r-*4Z}z4xqa{nrTdp>S_ z_W#?rvY&t2-@lDpeml3+Q7q?B{h#+axw-$&zOFs>bN-RSu+Y4~fAU|}@0|2s`)B^? z|6%#BFJANd_h0mBy}|i&k5zKhuHW2y?!VX1`!}~esb7DW?dSbpQ$GLK*ZTkT$9h}8 z%_{TQE|TUH}8I3pT6~9{iLt;$G85=FTJ&Q?o_4^;xYf*9mR5L zTIzq+@BSOVef!<$xBtUF)vNxuU-{?$&37f+w#~XbcWv47+mR>#?_c%Do;7lN;r`F{ zl0WzFym^=HT=UQUH(%$jee&Py-})#2-!K0Ez0Az|w)W5e)2IDco*}V(zT3b2{F~qQ z-z&>b{r_8}K7X(NzMB!%uXzuj4(v+)c$Tf^=#(6z$(kSPMT65kZ6+gT#b^rUV?%vBP`@i)1{|u?r#b1Qi{J*>QY~S90`T4o)ul@J`xP9NdxBFTa%H4gl zZvFb+$BqWy+*V%yes8b%{R*N5$vy$JB`VtT!u@&oT zzy2=SG<|M+aA-uxjAJwJ8EiRrbx;0LaXc8}?hHbOyn#V3nU-8rjNb7q( z;l97y<<+W5XA7sKm8xvW`0+?0D<(*s>uk&Q01I6n&9E<9^TgWYUf+6W;C0AROx?Vi z$M;J1gB1adfhK%w_b6!v{^IGnD>zj(x=Kn_e&zY2*D@^LU6W|k$WIiCX(@j{vEk6( zRT;XR>K~uR9`|HenWZXWC)a0j_|_A9d!OVyj(0?aGc76I2)J zoZ{|$VImd%xlX`;^MoaA;?pCpNlx*Q>3M9jM!Hr^wEONJuSGgne!r}itl9hhUffk4 zk(D>A?oDc~WIUU|_MmM(!}$k!6@8BrPVjo23hwHjU(Hm+{@BJ@y zDz@Rbd-res=DjyFFaKMAJu83ft=t*^qxa_JZ~gz<t(JJkwWLwS2q5#kvjCgewtR|KNht!&sz94B`;%$Z82w?;%H#O->rFJzQ9(A%||m! zY9;vf4)Oe29OS?6{rsBsvt$on`1bPt)~%D@AI%TQIw}z3dO5LX>buzU44*V4mM>h! z?#U=P|El`SneTfKpDuV)%^dLIQKUgH+b%crSEs9-ULW1>Sl{q_|Fy5zg8$5~_uB3z zeQR6Ltg}2P=DS?pY-Mm>FSl8`H*NE?tFwG-75a-_$HNgICT9fxtADicd)3^w`UKC16R-BW|1TNR`)$5weY&NF*n zOa5VL`g!<6N!_(GlM)2xu{CoiZx)WPV3@hDYiItajwOuGt}x~~n`Y*%ot(fXAHcij z;;y=HJX8DTB;B!HR~_QreENfHO_+7w8qrGWS<`fH@7z%8lPK79?An@_GJegM3s-R3 zPFK-bGhow{Y@+{IcNSt=Y`S7u-Qn`hyY?Dfr4JT`{>(rZmU-WHK z%L=3K#U_(kR^$q-Ikt?WR_#k^S$s5e&z7%YiGj!Te_W4ZZ2bTfd-{ z*|_KU0*0oLFP9`lw3QZZ)|A=zQsWzEy_#hBx+!;IP z?N@uqvB94GmHW=r_=vBp64w?uPCoo@?vIp<+t>WezV#)M`AVv>1mDEXClB~rxSwhW z{mm3EaGKY_Y3`qtgPHc5auQ9?Do#$}h?dqkq`CaFVAh?Vi6Kt}o%k1MyKXdU@QK?p zyJE)VTO7Le|IKDM2Nj0in_yt6c1ATjDYO4mviL#vAO6J#R;x`v<-M5mPsc04ELrn~ zPTtD|nZU_T&%#S<7k+p!sYl3bUHZh_58I@_dhamibxZ7vbUvQd!cn`N#pJ8sn~+33 zJIT4W%yQpsua%#Wh`Hp(Cx79;`#&+l3P zvGAmGD4)nUW`rh8X4-Z8hB#g*qXC)7;(S;AFP+Gm;9Q*^pvjI!gEgXSXs8r7M4tRUb=f}X2n+>siUQb?=W%B;%E4i zb?({A%Dfgw>->9+$$K@FTZSZ8HSjyD0XK!ym z_wPM-;98OyTP?@*{n;P4`~A;(WN-dy`JdI9rO$K9i*-J6ttwtReW#byi_KkPpKfh+ zw&-~Ff>~|f1@Q%u6Ha`+HT}BjmEKLC)m|JwToIK2Gj8{FjT^BN|IXfh_@3cU+2W*Y zQ6ElSt!FbVh`3-|p!vy0yYa}Q6P&$Go4)deYHumKQsSB;w)kam__Yiv-r~iJkKNo9 zTNoF2tYv~N!z_)r$2R3_7;N}xIdQ=ynQ1QHYg3`ehq=QSU> zvuX&}BLLGzCN+VQB-`p^21qcx4r2~o_YPzcOJ7-y7m8N z&3$_R`OoWuj}F9tY*`pTdBTe~(IQ=X!9Pv^n_2W9JIwM+|8+O#uUXI5d&$P|{x+Dv z)R`e9*SFYFqp_#iq`H|eTa_zIQk3Xk8o@TH!h||T!pnjLC&6*%4U61@_%yKvMwV-iqWrY`WO7zTtHIf`jW543oZH=j-at zY*gxtUbNZgqJ+n;<@fjgjk7=fD_^LyJJ4HenS28si?XUcF_}@cmbB>4Fp{!0Kh1dP>{ylJ? zxA$$M!2Yk%XI?q++j30yoFbHx_FRg$@$Tok%I}4xMM`~=sxRvAEjj!%CGCn4U(2ss zvXY4fX>$)SrM_T0`SfD*6CtsjE0r;3LWK=M4(=X@n9SH7{&LtcXX%apHJrDqEy}cf z+B~+sStF&mBxe8hZEIbZZ7H2}>eXdIg>5gd{|oH8>>>9l z(&9ma!oqKpjug%bzf_{d_uOZ?_L1YCc1=oW_M39)&w+D|A|D=3vbZ}>`_RMOne~e< z98>Wt`1C-=X!nA&sXIkC@ycy?{-yakMAhT9)zw9Nr@#BTP&U2tWlh8GMHg#q_Fb%T zAluY(_5Vf+N_G#4#>2fuJ$r_+GP{?J4yUOS-pM1uSJ$mw_jeGF8V*Y^#5yp`TxnQ zuSVN4d=TINf2nmy?Uf($YtO#jCi*{Fdf(c2^|gzB$oqfa8~!_g&)((d?^op4Rn)z( zt^SvEzWU#p-=GRsHX%mv)f3Lac`TBkT=bNtLzrW{j?fa*X=kL8< zy?)-iy~l#q?>$^Upa1@wyHr?0HAIhA; z@fz{$J=gmxu(za-t4dX_UHHZ_44~G_xx*^?y^Z|2L4%x%2tY{@6eN&*rV)+Vy`As5kz<`sDw2 z*R=k9j*t3xzR6^-)Vue!Tu8dhP$! zU+?eye>>)8{r^j^>#O8=9`9>#w&~f2~*jAO7io`K14I?}e4C{{O$~llCmPk!OT)c?P|PuIVk@_YA*|7*jlK^j4Q^|gPFf1khI`s`W0 z3;VCeo%}!bkH2|J&g__U$i$R9O zPyWC5o98TE#nqLJmEYC>-`*QnKKtwcbJxP8_ieY@AXXCg?Z5xW^gaJK?%Vgy@=?#b zs>45XWO$o&V*C&1)QYq|UijC8eV>HV`i1?+KVJR*_=kza`}j6a)>~ewF7s@TG;ze0 z%PndDd{JZ9vj>HmwdP8fq5{kJ*0aa7-3vG}!Sl~$t_KsG?LC}WYu)Z^FHFvH2;^z} z9B%$$v%%%S>03`-cvj=Kn`d6%8ULRM8tS3l&^N)bApC5@|95-88a$|X z@34RC`r-e1Bc{?)gOf{>1GJYtlsarMhxgGV)2XV$`nVj zMjZ+9nOde3tl|Z?toIQ*QP32S;md#2^Fg1%&l{1B`VYE(bo_Y6oZq0Fl7Efs{FbDM z^!tzP9x+dL4Rg>qEL3n?B7M6pO`+KY&OPNhL z_@5`=!{W!i`e%tnmoFU3tBAV8tK+o(Qc^?elTfYPGul;4wh8!8Thuab%im;!eYv-% zzuUH$HCNoJTdhWV&%DIfnG#(O=KbJJH?Et})8*+NaI41n)9PCnCu>NaIqvvqFQ0p2 z)4@M|+3`>7ohMwMe0q&wda>I=v+Va-ZW@?{zdQW2{lfC|dv}QJkiTBP%E9|n!VfFmpC*0B z6Afb5dAhDYeJbw6&W$PdM+~wLq!xuL-?VJ|zvI4I%t6zq3~VO1lidzYW?*&V;aP7r zNla;~h_=Y`gJHi?jve67PTjG8{o0um3lyEFyL_zh(D=$Z+eYxq8P6H4M^;Z*`Txoj z^|dpX?{8y{=n3%H)5x+k=wv;MvtQ>om$f!^Y*V&xuG5~Wo#(MG;8msMX6H?QUu#4z zYMW|JX)w&vt!rnD-w`Q4r@gtmRK`l%sk7;xjpfOlSE5GRkLPxHEoy$6=yj!HT3O!5 z7dP_7@3;PlxgN^COLnP5MDHQ--ASUl86pe`r9SZ*xju2x3}?HZ$4GQXGiulOzl$_F z(k&6pyECr7bC;`F=cT>>&oqCW{o~`8WpW?v{4Yy1J<$n$DD>6VoBNy2l#{oD8;%^m z?>=$m@qiUmRj+QBnf~#I-;O`ej=8@5pOf;*JV_^1XiLI{4jz>)>S6`wS8Dn#@s#>4 z^WyN9L~}8VXeQojxv=e}kM748Uo4S`dtcxGO5yp+r;FNTUY_;%JL8nzwf^h3&$+25 z7KvSxU3}~O@sNJu|L45Az8L&+nc#C+gi&%UGW+RHvJ=w;lf*l_Z~oBuz13O?VqEZfy{AWH3O>D>o&*Yr(%TKishMe+`VFPGo! zwQc)9v;Ff2W{1DeYY%5?&Sa?YiVUaZMJoX7Z`Y@?2Hm=tr7go`rl>o zG3izd84bdcxJ56>S z!ZBjY5fE+0P}n5EI`nW#T6BQuuuilt)BnnZF^WQGDlv>%rD)oUH`w||K0zG1uq|{NK}OF|1@3iqvgxM zU1gf{IhHcHZ`IE_E>gJu+q_LLzRvh_R;bR0E&1o(7T1|c44aO}FYJIxv?c94Q3)^$Ml74Kl6u0G=TpD0Hd3NldrPG%lXGxGQnKrlhn)WF#*J-hH z8aD9GKd?POvYzMshbz5Gk=qMX_s{HE{L;1gb(zSXA6ZgrKTh$4$ht?G@i8t>6!B5a zowap4m#D^-J>}bKSZB0O-m+=U#^_$7^N0Cjj-IU8;iqSzwRi2Mk8_qRDRNiJ41Kri zOV_E{lT^Z<&huKoVoz(yv2wM$H*a(O{$M3DMdVgsM3_j`k_{)h>z}?caM-)CrPkv7 z>cumiHn{Ba4%Gg*dV_VvpCrAXp_TSr`*LT;XhmKLKM=W9{H9{j;$N;ie!11YTD<A`npF}1sK!BfX7+b0?nx$7nAY-13m^W-vAy+x+LoO$hrBg(Zahm%nSEJk2~SJi zt>-`Q-@RbG^TG|ipq2N+R%G1tk#{-emovNi*dE1DgZk;hLDtK7JI*#5o4m9=@NQOp zAG7iMXuoCu#N&5~wYewAY%^J9cSh=dK(_H=rq(M{QyI(O@QO{y%!rEFW_wX$@0ORh z1GXG5L^!r;qliw0%>Z{OWzT_pGkKg1Nw)K7g*O1-%1(|Qk&O=g!r zr7|@+{aoMvw(a}Y>o0R_lMlX>D5wbCZ7n0lUS8jB~Iil>Yy~#^cqmrn&RYH{CKg>HqSF&i;ZeCep`Ge4DIR{=hq> zaQBHy7uQd&vD5AyxWt>jbjCxcz-4N`e_45p9f+Q)6=fN`_JhLI?M2VBT-QIzQJq%j zbZo`*^G7c;*gOcotuXbQlc=h??=zE}k5P83qJqRYUMT0*yjjv;|KqnsgdLxI>QVN| z&l=dJjgFLGf1I`P<-?L6KW^STIr;B&_TTHj#qG7UtoZZn?7i$O4B7i-Y~%jhAN*Ax z{kq?87XSX3|DWXJukFvNsr>TvYDD)z)7Z^`(!;n=5#xmp(qy z(fEsH#X}{ZzQy_m1%AO*d{!q8sWYh0d-VH=rOU@7Wi_rvESJk)y5GH!t~pn*Jovs< zn&`Qr>htk`fBZPQPQ3T{LrJe#iLVJ04!%0GS@wj{1dF#-Pn_EK*RIbl6W<^p!St|x z_6fDEr@l=Rcu_9N$L(8iSH^BNH_L3d?~Jui8S{4Ct`PE>sPz1xYR*-)&2QSSp8Ozn zeqY0_)V~J&moNA^ZC9ML$Nf56kF{{bq4P8S_9UfL6fN+tUF(+q;PqQ2|4w6Pou_NA zuc)|oAx&dJzRf|B%2{W$Q7>1I3Mqm24lKmYvwIl)%?VM-)}#d-v4@yq-A`*&c0@hh{cGm* zM!`=7PdnSZZQbf~AAhUK*z<4a_pJXf@AYqO+j`wKdqKsb!;2=|6I7X)qp*JB`z59t z7Di&%wUnPsba-I|Nh$`pPG8qHm{<9hTx`6~5C`8OoleAi?bUK`-Fnl!ZUDw1slTe@D3AjPTyke#}WY{==P< z3={H<4;Gi7&TwM?u3QzhY2Ve?rPY>KXEztl;W9V<=xn39W0~yp$2H65GQIln!+G<9 z1r>&Gyx9sRn}5F1S(q;Hdzn&9y$SEl>qYA(1ch%`xH{EO>mnDCG@%Z#_!DMA`A1~Wb+6hj+wFMMi&`h{zhQPhJ}@v;JS*kVcDL$dN2)jOuMeot zzF~Xj1EYez{q75K0@uA-Q$8Or?Kt&V;llPb4Y~GZ@;{nN4%cW!H6J{GPRd|~*m83& z{wrP9&Qkx68+h(fV(?l1swhxU`kuDp-L;P<-20GHXlgC6ZQFsM83o0iqML=ezkRNW z%hp}AYNIU6WpmGlV>37SnWZ+*@2p6CD?UZw8U?(l7Rg+;Lqix&98Hp2_yuFRW+F!`NnSS=7qf%@=#fc!_Mmnp-Xp&+j{g;Sa4mY#j5 zy86No!|IhH;3{x9J_+Ro**lOhv|jye-xtY0d>?~Jbcl@Q^bRyr=TP82@WRh{zK>V?pxyp1)|;X__YFN7<+JWQ0+{%7_uIpC12X#(euFsp0t@Ziptt7z>-(Q_wXQ0m=ugtjY zn#SCnq9>Spp06mq?DwlTxH$bo?^Z4^p^jH_AsNxz0~Oyd@(at%Jk52GE2z)GX3q5Q z0lSZgHM(8XT;Tro>9?0Ju0JkPIm)sutAFBWxq{oNZ}hH2{`FcS_0~;O?&;gp>ske^mYj0n6Y(Irk3grrm4kJak@J%+zCA`s5>=l-S!K4 zc0QYT+OJKs>|M6$@b;@=?-oejkJ4V}vd3p?)U%YMrN!l%f0ub}`6Oz{@=aR$&5cd& zp08TEF3ESz-twi{e|guG;Eu$Vt>G>^w|v%_=-+tC@1b$s#J!j5WxSW2%{sg+)hss0 zWN*3hi%rWmd!3f#*4h5`%|G1~KH~t<=DX8x9^YYD|47@MtCBT-ZTfbD9knXe(Rm%e z$`;CI&D6bI6u$lFg_+gMcAx4$?^mOvZhPd`O0|HxjFe;c3uGs}&RLl_*Z23Yo0}d! zZ*UNqyTqYu`QjIAEc?!HIQF`Jf|}Y+v6r%9tqVi;E>nC{%No;qgCW26>Dqel{ToGp zt-Wv{@> z>;A#^OYQeQxSf?%jNU1nayoonU$kue=f_*-%1qU4+Gj)la4=mnQ3~iqu=2 zom3&!(I{YNS@A3AORUQ4<@&bg7wW36cy)HYwDc36ZyORjwM4$h7;j(jDo(&?X~y2G zKW~~l-20!_@^Rj%bh2>n=Hu-mI^-env3*8r3ZhT@^;hTwRZanNO8y)Q@ zS^wx%IrLFca_1f+7l-ym$sKEQe>kfwtL{izD)U_^p8aZMWQb*^asBJ(_nSJF*|V>< zIFx$$gZxAR>C+ZlG|HDTFEI|i@&D!3d#@*7Um?7G@A|z}&!@*7PVc<-Hbb@Ul2^_t zp|`qgkL=&#E!3aV88^GJ=6}`yw~ZHl!o_Z0V_J6{)(?t%ypS(s* zs(#=9)5qJkRqx#+t$w=n@b_uI7uRi3`7v4R!|A3i2e+&IsMkHVug6D~x#@`D;)a|e zrYTAvju`XXA1YWe@52AD>uf@JSLFY%TG6mN-+pEO4DDF~_v@-wn10>2p(RknJL<~| zDYjql_zoYdt?`lQY46}ltUunmd_qfO$bzq*ckR%f^kL<# zyEYvhNA_9^WCpyyTh9?y_=7L>urW`r>GH*b46|5_RbxGK561_2zJBT@rIGe9b;g|| z!B?K%djC1wKfJ2<>>jt{D=uEjV)4HApulO@wpPIpoX?e0rY0Y@yk(QSNSn*_vUF*r zn9%lKtryV;UA8CIFL*lBJ;pc6mO*KTPQ-ugE4H6>QlU;V3p7U-0><$cx)!E1k{@?0Jy^Hj;#utZLC zS^ina=OKGmOZ5tYNBkke^R<}w#3yG5z18)@0 z9%UOhr~79*UI<@)F(7ur^zf8~g%Z5|Zikai9D?lrd=?O~?G;yidV62$<(VwkGt@o# z53z`wzs@_n`MLhLtk#WkymNW#Jr5UFOip|F#MPv8)1N%i@(WkL*%h#D?azyie!BK? zz1jcv@QC97U#|bM{P5o5N$8#L6~!lC|I!Gaxc6$?4Dat>z5eb=vtNHNU4mng{iE3{ zJT0Uil)T>l^x2IauURa5+rC~ju=~5!Ag;)uTZ&a&ciCydqZ?T|)+ri9Ezedcm6WX) zomp&OX?G+;peXv}i#Zz8VVeaDgcHg~R{;q)xgWHZ~YD$&Of^*f{@T=vdJo1}%AT}*lz9h$z|vi3e| zQc0EYxq5Ta)zsr>h0XdnJ~f@{V?Moo(x<0sR`n$_xi6&zI2oT*>rLui-m%x!%tKG& zeMsQzq$~GUo10#K;E)sUtWxgj<#cw=3cMYsOwT%CB;NS$-qD?_hS? z(vLQh0UMkeXUz0%YY*W+!ohuPO`zDf7^a)Nto9;&CO#hy-6`{aa7LNi;qj@;>I)Is ziW$2mr#97>v3=RnICWLcb@55H*FOw4xEst|2Wa4%foiJu6gEGaWm1S>klXF=zl*mlUFxSWqo+O z%koGAj{6*}uf%kpe4Uo{FgNQ`)=9PvQG5R|n0#M*>V1*hmih;e%b%ZC@Jd#l8T+@U zZ^8=8oXGb#N7=!Bbt`8pNH6*G?(M_#QmRMwQaiOD?zp^kaiyDUZ?>)gS6s z$TDT0E#3M_f4SSeN8kP(s$b~jpR~#B%Dxq$o7&HVEi7 zzW!=U@tf=GUND6J;cy9IGva-5dWPkL_4D8Dull$-RlfKK-;?7@dy}Wf>7UE07r&At z6?Z4f`{IY~b*JYP@BeE0Ip*Zm-PU(rnKH6AGj=?$`UikbzEz>h>DBU+hV&V^Ct4#_WFU%B|p#CeZI7WE(bqw+gUfB%Prq;X1MJ`r_IfiPb&`UwC*aL66e+#FnNWM`ix0N z#%Cv7;##RYnN241X}tGpj7C4zJU@BU`2UOt_@OIq?1__ns9_n{G^=X=z{( z>%Q3JPYUxB5C6j-7HyhcmRNJrWcAD$_frefTQB}?33(X!uO%h&gkmyN+m!^5edVQn z{1)|0Njh&fFSc*dP4=i)&JkL8V{c%Uv8=;)JI8Xj$CXuaH{}J>S9`uboWJJ%!(Rz% zwdpGFJ7e1C zhqA1Huhn}?Ogf_V_+R3Btk}z)mwH`WS;a|cr^~U=JkNtnO6&F71m{kv zT6(7aYTwxtTh6bVF*VBA&0~wgjo@qXNhfwJ@~+}mIISO&v|Db%qtKSso-f1FFW=dc zEPLX?uGWe#M>AHl9(fgU)l~74&IvASgOUV~{QRT~Wfe=KZC>7A6z{+N(aPZ0O9B>O z+<#xmbn=={KWZ7aocgf(`#v3=xH-|b7wbbK4<)zGT)X^~^Wp7Q;TB9itvYd1t1nrX z{QM~|+qhxBR%33G(?0VVPuwNu=n8*QTC`WD$>W4~hrzRX3-zAgRLa_UYMYW@x5CqT z4}GVnch7jGHG6U7>NnX(JWnr^?a`mJE+%_zH>bA_Yf|@{Ct>2nTThmJ*ch4jkmuq> zGiE)u`t9kyo$EdGH<(2k4m%~Ago;Ma83Fpe4CK{-1&~~_U)4J)0PGnzp66`(w zv(BZa-d#24V^{JS{%b4iuD^89__OfYk-5u{9Fn|voo!i4*b7&$w6?e=B`83W6 z>^-4$Qg-Q0123*kzrS%g&)gSa@ZeGIqUc+xYc1H0u2^`e{&&lPiT<4@;|}F&sMrhr z_AFli;mGcPE*4Ik`!DHnx`&IDJhIGq_Ttlxx~AO)of5OQ-S^kMw{PDCd4K&|?_>K- zzN}uex#GYhv*X`>Z{D=e~RX=%OV(Qnwt-sLoT>*2R&XOxT9lMx;9lm79_Vn?UyO}pdb54Z~x)doO|}{DSP~3Tl>E4mg}azQ=fKwhPRYn zvdPZVikCmJ`y88`u$0~Mob#ODHU~6i?mg(WfBx`nyX>7EygHY^Tg1L8sbJhM3 zP`)tNa^fqFnfdEZseUUri(WC?_{U?1>wFoXRrWAtMk~eU71kcJ2|avb?H7kNAv=9| z>^ycoIkN3}^}_1yOF!mb-*J@5dq&ojcMtcu{hBzvUze;=6=^HEi`2X)~yCY1a+1d;bS&Oww?H`6_Sc-#?i1cIyVpIb3)3yH*Vw);?_9csc(nAQ zi(8a3CTw@Pp`hxnx#_CAz^u*oiw@{qXI@=$;8XezyDJS-oOi5$;Z-bR{n`4)v}aE3 zv%_ypd$x4j(wz%;pM5VByHexX+5qpAh2qtDJ0DKFxciq;S$MqbyHn*C7q9&HC%}_o zx$DQ-`yxg5yquk?WIpqr>T?CF`Xe!FPo%fsoT(SE;$7`Ky|)wop3FP^WO|}T-`*do zm2an8trJgOKgUW@BunbN+UK4^nUfy{7ESLmYmk4Kv93bo`uo+*JA(X9%=EE#5$@P^ zLvV#!#=){R89&$`oH+mP+f}Axlj2S?yq5m4^4^EOHqn?i<>r{QzSHT)GFnp3WmvAO zKdRRn<|S!aeagCy z6|ZW}TretGAu9dXM&NL*K)`!{-x~s1RrB*wGeR3yq}<%S_`75E--&^-kwz=uE67jC zC@?(}s&o9xVTGp=7bk6amN|LH)(Ba#!?iN8LK^j~vrFZpcRsOYOa3P_?LBLG9fWA_ORV-r^7u| z;#i(Xh(v4eQa=5uXkB8V`AjPx_4%i3s)`aVl}_Ea-NkguK2Ka>6~`n2N5PX1cy>B# zMn!fn3o$FNw@=@sBX#$F`jjnd3v#>?nA%WsK^R!`NGx5y=ShQ z#(FF;X3kvMmQBY*}K@{ z`z)I7Zd8x4f2vz{PPt5U=HEGumcqOoX|6sGZEl52i)ywSr`JcFt*evuPRR=Wee0;o zxuwyTZlPWeeRf?=N(tghKQ)_U#(nd5Y8`)cPMo=y(3N9){>^i_)0;xAi>IVdGVhw` zsX3`ZCr#b+@m7o1GeZ;q}^86Beynb!XqU z$cHi4K7Ebxdl=KzlyN~IxSmCIf~>EXKy%QunA2~w7g}0OpK5G7Jvb#lM<}@K%#qai z^`|uFaC=X631^!;^L$9y@i$z{I&3CQv{QB#*>brTHf3IMc-+Oh>FYZ5o8BS+0EvlW{ z`i3p;-E9f?<fJg2%6HGbcK_C1zM8!4(Rc6N zPxzL9sQvn{DWB!9e_B=4{ptUL`q!^_>o3kU*>y8EUR=tqm`Uf&hUR$J*cC9H~x{XKd;c!o%>Rz_UD)_ILBZ9QPgg>#_2t4Gmp-`Ca^@fKDKi~ndOP9)IT+Ldp)}I|LuzZ zQ*^~tI`p8kS#UMXogr-HK2C34VDs^>bsO+m{!O4nG!Nck`WB7b@iLe6FV; z!BXSX-Qvf*j(Mj-rJgVN(%`gp?z;)hz5f@w3Dzad;JoF!zAcdEC(=RJJ+XQZ)rlVgR~dUYeyXO|`a ztXiCqVX<2uJ`N3_1^Ir=zDK}GwEo;_jQYw>MNPdnb#Pz@`smm z=u49`aV*OpR^0rQe(uwy_pKVym%E-n)cL}-=crLqK*w^Ss6G3yJ@W0CVzb93yZ15Q zQ}#JmuB>7jO+2^M=Sn2hIN!h|MC!?$l~yI;WXJFlNV(68pa(zz9&<+@`u;HoPaf9;`-H@ zA)603oc^&}Z!;>i8yZQiDxIaoP?rCGxF`=#-Fd7pYhQ(}Cn-Ha!UGI!lJn|QyNTbeF-w1uZ#Np9Dhe9QML zwLjM1Ou6kTY#leho?)u$%cyvCsSa*znr?bcTP@Y9F)G?&qa#5Bt2MfUC@^|Cn>pgX6n%1&Dk_5H+0j{IQPZ2S#n+UT({<1yLl#yWET3lo&OWH ze#fN)jgp~nv>ersSI+GaaXJ4>tT--U!glr_SL+yzb)b=&5Mz=o~rJKuD!R8-8c-*ErS zNas?RSja4JnR%ntD7D|MMzWabTuiXb^x zY+AkP$n$rNPI)^y1$m&i2Z4~mBz zs|r*zk1bjtu%ygWaM6oNx9`N%mqK8Q-7Isb_22J(e<3av z_2quDjpp+DmhagaZim8WT|ZIuf+OsG#e}GQGtPA(t80EwI8gNL=8IW%-SaP&n4SO9 zqO<$q{6)G}%eU7Hr~WQsNLRVMGI0LCP{}X%wmkDFJo8ig|Ng1}?;rpAKf83>tl8Gq zd*^<8cItor)Bowe{y$Xv#Vo@h{`3FV+p|yoUw`-Qg8%W`Z^!=pU;j7o@BbOT?_Myh zc$BsF&;O$T_RHQZFJg$9E3?jzFI>HS_2k1>PdY;4aaK#PiQL8iZ+}$j7QUVTO7`l7CzH|xuS8w` zdh`1IG!fO_)_IJYQtrKv=RBD1TmLz+k!!^!cD9_E6-%6Z+Ag$Myu6~%QGCrP*Hg*# zj5)8xN9WsGAF7{Pet3{|qNH8luKh^)R%cg>*-&n4XjD=(HYotasY*^uQimm%G3>6I6I<9|;nZzzzf zKX&=&6BD0TZ|d&bkAkQKsejhfjNVJj=bwxU+cCvU_qEgdlfCo9R4m`=->J$IBE1XZSs-M3n|GDv}1BH>1(wp`d70vRi&R?0f_o9LC zifODhhx!J1xC)R~b)~=v>}3`#8h*7mQ5e{asU7e4^U~ zvfoAIg}vwbADppcXpc={=OeUI_;s7xK^ z7q;sS`#!IAO~3ZNejUHaHvVp&yR4_bDNX5~%A025q@^n(@Or|>^NVt4nrPWC*>JD! ze06g>$Fdnm_Qm{A|7k1NX4~VdUbW^$wK(tePwkac7eBN~xzKlgLR4Qd%U_O`{$rVM z7$2Ug3Ob#0*W~W=-RV(uvsVD9xk_U*z#rM--zd5>)8v!o|p{(O(&3CI5Gz^F!EdxL)Qh=u%*rQcmsnd6YY zPchoftIhh>wWV=9Z&@QF82w*ZUo4s1SmD8UVa1NsJp$jDH#BW}Jew;Z(nfv`a~^}y ziA@Ow`wV$LItM-9EuUbZciUmY`-YkeA)1x}x976dN7|i=aJZBI{gw5nTRV zPq-~-dX5RJS!eyRdvXOOPL);SoXY#Y>HQOUZ1=D^-n#Zd)~{=CPji3#@cQOvJFPoH zKGm|jdw2cjd~;iKtsT4EtFk@f)hAYaL>2a5?{+`JQgVKRd8K9Jwek(+2d{EUPV6qY zqSC0_wm_(4Lf?fIZhKv$r4Cr0ZGUpHYIiY@?@><+k%sOYOB+HO>empX+rngS$wdb77pB)dtMqR?C3j*~K;o_ZpH_1} zs@pwV5E`!Zal%Z`l5Ptp7CVJ0_03bXYLj`Q;}>&&bDOQftI5ZgA2jJq({bfZhnCH` z;qp7cY<}kg#aWEgShzR!ZvTHvS<~AnOOR*&xp?U!ZQBWpcy$YY1w1c}EW5gRp-VQi{1K{m zm zQ-zLN&-a};r|;$*AAG;Nr2g`O?|!xX^JlsJyW^S|*uS9X`-Rt1|CW4h@Z&Sh{^XpX z;P-i7*xA!_>KjijTqjZKJXO7V!Q-AiRZLyiKdbNbcy={T|HI>ZuMa=}y*{L|etT5z z;scw-`}f;dZu`s6($MB=zU*|F!(Y3n|GR z2ZG&}Uthh_FDKV7b@KcT!CYC%2an&kt=#qf&2Ra6|KtDHeEf9vU;V-Ve}8>Adt1K# z*Y)%N)h%QhuFsq6zCW%<{c^=Oc>$--r&qt8{eRo7xq3NC+sfr^@2q$#{$^wRzV8YS zrxndAMJ^PI@Fg(w<_oUb^!8JG)HbvBhYR$QRF)iJNRQZG_T}{Bum6SD{NKKn@9o$A zYy;zLtLrItTYD3YekSzEFYn*8-{<>Y_Dn;Giww-a1)5g62&AwYye^dM_0+z*(aXNY z?~uLf(%oe*`KG;_GUeVD@A8c$*JG=?l&v%B@7{d1#oWBHoPF+k^XUFpH*|x{`{!I;N!m5`pJJhY?=NtO}6$_VZ1*%!Lz?!R4OM^bXUXERsHIV6@0cD z1l+4$9&jMw#euFQ_0zWx94g_Rbfz%PCV64cWr=C^H!d_S+gA8zgPZ&DkmoNLYd8m6lJ`}5>>*c zXLl#S;c3U-C_6SM_xelC%eweieGpZC#1OUBA@Sp>t?F}@eO9qqz!7#Xl;c>S9#_-M zx|Qbp^Kt~dYZ+}?gYI`s>ooOxl<-2tz(^BcwfnJ*G&797C)9>-0Ke)tvTlFSEp9vmH7!CdECiu2D~1xayU4 zPU`8GI^JuiKGx2wnX+~9_f?xT*Dm;ds@UPT=GA3q8LFITecbiv<&--=LJfA@jM||Q z`Rhfega4H5L;vC>ieF0|Gx>VD>VZ%qYyCFe50WEU zQa`gUHh-P@gU8*of=$j;6ulIFJ8g5$OU-X5pHFu?E_Zq2vj|hgTK&KJZw^0x*z0#` z?VKfF_4(zQ9ObX=mwEKu>DN7G$<~T>&o}1%yDf07sAp$=&tkPT+d8(dU39lH;+=*@ zo~e_HgII4s*)(0LInNFsJ1#RZI{3o0pbM?Hh1YuhE}iZ0dne|Fti!&J2A!dDR?V zQ3esac^$`jmiqs3%zIzIWvRg1b?aX-Z<3!P#kc;|j^*dx^3A-Fu>0&j?;ADwnIGmJ zJ9*^o@wXd(dw!OE^LdKoh9eKcs?Ih&(i4?l+PPf%_cYEg>1T|X#d5{8%b#XNEUo`l z#4A3(TTk%-ll!mR6CG`>k{3=akFzNcYz=(r+AW#CROW@mvH8Drwttu;$bF-JPt&gm zPXCJ+9UM#kopnvmzO3i>>v`nGF4wXpHQOYw&8<1)cy%%R2maZcR`fOJ1uW16 z*qMEB+SPlN+7%}YFJ#os?q2=WXN|7%vD|uvs>5x*XWso@y@KoKAuR_5&qC$gGyAW` zhWeiHzgxx1C6w_zy8p}irEex5J-sU8s#(RA%xznxU9;VP)?UrGdr+kH?eoWqJwL*h zeVDjlk=3D7(~gK#yx1x#6;M&B5_iEbS5T~c(f5#tc1&`sAG=LD5xdl)tGLKv9nXBt z>cGI6`|2&HT>e-!`{m{Nee&Dxp3=)I-()Dw5;86Mtkl25WtsAO8x>mg6)K#|6M^+rGk=0+v5o@faWp?CM zcSmdJHQ5(;AFAbEb@%WbM_^-dL!_Qyaz9xo_fxx&GeL)vu3+@8y2IV{7!EWgFx?+pk%j3#IRTlJ%5+Rc4zVRvB`wZMG(7kFNFV0~;96^5&S# zTmF3B>DNnh%nBmYI->8_Yu5jJb^N$~nQg@CWgo9jS;n^ZEm!m_qe0}oVzG(f* z+rl4a@yNZ-e7f;6-}0#6ioP#5FYuTqfBaY4tPl6D${Ag{!_Ue5cH@#;`=kHob-wM6 z_`@RjVNUOU&+231heAW0UqAgEzDxeYwPly^j}TaQ4&wGK*T^*yxlh4$5?>&B7q7kZcKTQ!|f-l5vnb@&eZqMOG)g+_gk z4O3Vz&s`ca|CzE{W1xl|aQM{Kw@;h5*LdojA}a#K7) zp7pNy(^(&uTp2oNxuM~Q4Fy|`?|+JU#Spfl)zbXg?K@j{e+u_|FDS{twdL5{eF|Ip zt&7CBuHIq0qe|)q|JGZ*Q^V%F>Wb&zxt}0%9i`} z=L5A|8(Vi?d$_0Wq~nvA@-tjxmT$t&sF=#16Kq* zldoSn_{XrLhIiZiW&wVO`p?=AzWia9_IY{mV89-Zb@wt=&IUS6%Ky#e74ptp^tI=s z;tk(_Ep=$0n%r3$U%Pc`zl`d)jmNbGO!w%mDwF-h)Uu;uT6}vz{M6?WTZNPYH|V=> zm|1#OVY?Ko(z&Eq*Et4a?~-Taa&;RhgeEGft0RJCvc>K$ z4_M~;Vu^ue80!Y7O^GL0>GibDeX0>$Tvf8_X~@|pwOcPcOT4LgE@3Keb@!;q+ZqW^ zYt<9wKT8xYd%S+Zar4demmYRH@5*m%Jz1Y>J!`(Gy4cnT?O*zlX?(XrPn(Y zYuf#F-%KXYlijDi|Gf}z;H=B@rm(lIFYNqMekIKQIhW3j^Q!*y4eH}NZmNcL#TI^* zp2D>t$%G~L`s%~xYgq3~SG|?E0G9q?KecYQ@Y&q%txw^d9oe2)j z`<6ZUU4Q*^ZLaMRU$%Q$QJ>1hX0caG(@V@rEZ|2Z&IfAhgPv-%#*Nf7dE_B*-s z?(qO5aR-mz8{ghYf0oTI3Qm!wV->@z= z;-ipf*Q!rqfp^Q+b6HJZdTZ9V$(x-e`5zW9H-Eh9nqp(2<Nox1}1HCP$xeHSGML*svzX@TJ6T*HQ!oFn`@iz)%aU8I-{(I_7XAORxZ?jwtIp=9 zWs{Dt6;~^{&wcc7isaOJ@AEF5^)<^#l(pL9@pnqTM1|?T<7uk@tsnosB=VuH{!Yb` za|aEaO?E6-J9B|Q)*#gAK*@4{?@PkR7^_8BDcF8$TJU{sdex4McEL&xt&6Jz_8Fd9 z?*GXuScSR!@C1zDDyWWUufQh)+&>^|*YgcA#5brpN9Riiaxpl-k{&-8MNx zp#Sm9lRAFf=4W>sOk%lFJKu|ivuj6VzE^!-r-bi=v*%Lv;v&tAqU%i)A6=N)%kauI zr6l&l&o4sXbe#J;&dhbR723aGDzn8sYZ1nCvorMnfzAN>(792zye#V0&Wsmj6BoVh zSR{DiqD#Tu+643D?yXX>&tw;?$$d5T+Wl3?mr26zop$DipIpi(YgPZGd@R4HbE10w zEpgTQ$LY~}EzJccYwG?iYnYbj$~0%m>vf-fQbd{SME}={{{LIv{eR!x$}8F5XT4pU zSDjs)y_GTI<^Ng#?q|+ja`C2##PaXb|Myl3fyS_P$F^2@KUKV@6BU>}!z{|g_DuSfm(Pi+1wQ}VHJ#*Jrh z>N*Xh581!(?h=hyHNW<)*L;o*u2X-%Kf`>Y&Ubf=7{k8liSa)l?w_vfxxsn!)WqN` z3#=LMi*y)^NW7jcKQSoJP4S12`m*n@i?&RB9%9Lwa%$5L>kHeP_?Oqdev_nYyNWYz zUFXK@H=>_hS`dA6irS~0r^6WiVqVs3|9!vt;{R>8-mWcMzH{@{>MQTQhW)zl^?&o1 z{S^g*Y1_>h^e_D1=E$1z`~9=D<=5XX{CE9rS@>jwaB)W0$sXYfjQW!^!yW7Gc|yBt zm`$Ag53jzsVczPNJ8bUl=g+P_RKN8YLv|G3mjs1-iFw&4E$wF%az1)#BJ*MPlfDhC zSN=QNq%BuA*6$ZxcYno|iE~<>6lH9ai1$5w-+w*X`hA1Rd-e2t-|N?Zzb`lC%Huur=R65`c%?Y?-i}C9sblZ< z^|iS#URV($!^LTrcZ-pqt1+wKgiR4|)u#WirpiuHWe=%%_M=%bbdPxN(jz(=2C)y9 zhIlGmZR=SRVzi#+h}Exk5Z< z+^PR`zJ8Xr(9|h$mZx{Q%=TwsyguVnvpLOp(&Xd|uMOu2SuH>KAW3Gvs6^UX zE5)A@J<3|AejbhpZM~A+s=^nUHYqxB|0Bm zO%2)|wEMWdPgF~a)rEAOd@D0aMJDEx$->}0R~Jm-c?%#Pp}fNek`IDSws>d zqRF2gew)gfQu=TIrvK~S>~H&@zkKh_muuea*Z#de?|<(6Gs`cU>dSBc#2AtAKX>cx z+tdE%mv7#>chmoW>%QH$i>iM*Ra4@-v)uQ6RcaF?7v|5X4OdFu3O+^UVEwQAnOn=l zCRc9#m;Jhad#RCs;{G0ejyvx-Dh~d-f4Avp{@VX*^QyQ0`|tOgN1pQ^Psjux7hm=H@t(<(Gpu;l zfBig9Sbo;N!q}NRc#akC5-hf|Yf@@`&R1{Ap&<4sTI`O$3wmMdv;A^ z33o_evX^`Ep8ToemMx#3Jl5e>-^{ZNcAPyJ|xB#5z^h3PtJnoeG#0 z)5N@P+R!CA->=GpIf>MyZ|Eo-G4nt<(YS?|Fp05%U><FLuF)5=p&$gzdvl}P>WCc&jL(t+RB3g`!Ftf{rW=6Fy3$FY`88cBhyU6!1| zY;WduY%$2#tR#Mgt?ovuypG`9J9P^l+)}^Su&BxM@1Ni2cisN+b^EIQsnV(%rJvWn z%Fi^EJjTqt>BNkeVw|ozpKMm_>UjCkm38$|hgPq`cZW6Rt4D=J`ghQ}scD zS#mR8O_;yozE1a@zG)|>+~=`+QvUGu*X*v14{J4rz3(w5yyD*T1uXrI_=6_#2u_6 z#Bn<-a_+fDTl$Vl@nw7om{xJ?_pQJO>3a|OF5b1&IA>+SSI5}s^U+7QyX?Ez9Qo|6 zZibTVT;5j_${L0f&ffG@TrH~AUiPY`>{sH2a{}9)z8Aj{yJDxivUXR<+nW~J*WTrX zU6<-Ptgv!+NY?q@ODUZ3v7->wcFd&?fM_QF^ntgz`M!`^LDR$ZQp(DSM~Bm4kp{= z5-#1_5}yAk!#`S*anZa$m&%gD10ByK*0dUCLeCzx?q7 zr8i5mjSlGUXWR9EOZR!1(z=&rG2c9^PJfG%T@_ay-=+18UuH9Z z!37!Bk1YbFk^JdBF1uxnzsy#M`E}^WA|5v5x>{++GkezGo$>OD#=-X@5v(nZy>lLF zESt$JSI|}!?rd_U$VRDW@3Oh7rSTQhO}S#<{$N^hxu-JAv7=AAzSZ~EdaHvQUR+#n zQBnF;G?V?Q-&6j&;u)8smP+fsbW%Rf|9|DOCtv5!pR)gJXP10?!{aYDQmGjSXPWWw zOmsS1P`#UB3ePsFW=KJ#B&F0&_E|vcswKs0}*6Xix z><|BOzrVFA+S=OxL-p^Qe&1g%K7Rk<_j~2lYt{X4_ivd|-*fcg=lAh;W&)MhKi#f7 z{{GkOy7TuxZT~C#f8zbNBiru3`|)<&{d-?-+rB;XR#t7x0t?YMi4%3_b8Tnf3%Ska zP#?S4N%~Y!9lv*gXinng_d(sc3|m%)-)L*mJM>0~FIVSQ<09L<9jyjsU%2`?zL|+A z-PzFTyT(5w*YP#O35S)3B?G2a?Q;Ix{!E}e^7q7x?R?Kp?9tnPx#?4Mz*j*N9@`vg z(Oo{=I(%ybSIRB!TXNgUYs(j|Xr>>^Yp%CWa@kzZmwfdZ+u6d5z|FH;T%r~Fwx}HX z^kC~f@d$^FU%!9#zJL1eph z#INXv>F&&oMF$kxkLwjIH`@`+WUf#!*Hz-)9kIi6t6d9r2hCa8Uhf!b-MWYS{%MB_ zmP|+C9VM&PbL$U?KmDMpt^E8)V3C-{X-D_64R1cnzdbbF{jJ_glRMl$7+*;Adnl&u z5ppc^*S~H3?P}n!&FQ?ynM^f9H{7!Qo@Ju^|ML31XAfx}Y1tjEKI`qgdktb%i{1Ch z_)m9!x-0NQVzdbB1qJnJ@2f8(N~f*9s(ZyqPH+R8mY~|LX|rW^)bE*mz|PAjJ$lYg zi-+clqjP)zPyTc-m_G_>ycrBg=JBF=yDP*Rd9T{23ezOt;r} z>1=3mI+e+kvEiz2g`drXMfL6hD#ody|8(9fJr&nq60pHMqf6wPr^(vg&JXt62Yi-~H;X-+z6a{e1nt?|gA@Z0+uRzIUj8{rB(pr|e@_KAUE4xz{8rv8Q-J zm|bUa)lYO)YL8#pW%yY(BFp8+iHIU^cYcbO`cEh)pz97-V?92;=1?~oih_IR_HA|abeFyWeJb! z%$-t|KaWLJeQ9{j6|^DydA-6sKBmd%UIm(^E;LK)&cCKI$s=KNeI)zMkcip~3;;ifu&yfAnNfp7uE0=73sNyjB*JAhnJmdMRSew-9MFRXD zKHt8;U_sy7y5QYcB;6QN!DGv3se)%jW?fmZ^X%jclGDYyRL%FaSS|0q@OsCLi;sTon(iuG z^H%S~CI*qrfFj4o+{>B+x`khd$YwQu4X@9>vs3wH+&$svDwFfY--+)2qr;Z|prtj7Kyn)5rqvp5(#?=g%&WARujE33U}Q_82p1D3|BjhlDejl4DArtbH% z_SpWkdPA`{muIf|B)0TqclrChR;dCwgYxY6m^mcQ_?P4ohFCG)!8N+tY%m#fQc+EiOE(;OtDJ~N!1Q`+~L@QSY6R}v;9uDPOhF)8oo zlXFvBx)e=J&MdjJW2r@HXOQZRfHuYe>&4YNA0o747z*Aq-J2QQ6Zmzf`+ME+8%>|0 z=Ijd!Q8Hbgt|0AhQ~y?WbLCCXS*v}MChar5vfTc)%HE?jUtYb~_B4^9)$QkH zenTky$f2cW(k2@D&JTrpF5cx-ODGWZd+)y6IJ$~8D8tTT`8|;v26FuI^%oloN<%^= zm`%@a{r6(?#T)srQ$Km;yjj{kc}Lb))@!U0&VqdIN}i5|d;Y)w|Fhn8m)#N>gY=a* z^;WIq4O(~d_dUsTbq}N4!xj|Shf5^SLasI(*w1S0wF;%wl(+ew!4&{{B(5IBkdE7^A>AK`(|&mTyVQ@rQxoKW9e>+WAvSQHkvs`$+W?^$M{ z0)g{R-LctrWa{&$Gi@jSyyv_VUCjKfjzmtTq4egzw@!J0q7~ z-tl$9=Z3qv7e4B0%6z&K@NbgA-2Tnc^FQd@O^hk>=y@<-yu?7|)q-b{^ zr{Ayb@?zb`nONkD=9uLkJb6T9V}*W0ZQ}GZwR?ZW7wqmZWwZXX+)hNLOT)6ESEcB! znTs&vziQ=E&D^?^c1ed!{5$PLl24`WE}Nr$g_VV-vm&})?PRXKVRPX1o_fB?3K4r}YCHci zsyp2H@@8RkQ0{}vSL0h!`F|SeA3DRyQ-5=%ThQgum`h0yEvIeEm=|&HcY)}#(z(Zy zTBS4M($-(TCX}QbCO+@m=0jiEW){d5yir=V|sT)~uB} z`}ESWS23rbwB@fB-;(R}_~p6AM+GlLpQ9ZL%vPJWA>pI7` ze(!9O>K~o0>*#+cqY*x7uKdkKmo}}Ov*+?-Q=?XocRD9JqP}JnI(gdWct3G6v0~|x z)pcc1Ih}c1r9OC;>!b{ElWv84Z)3*DL?s3x%X|KFzW;yrcmLgE|8F~f-%wxhWrK0W zj}I%}KmK3!KY!W(?GI<{k6(T>Yx89B9a8`E+u7SC{^#GQuP?Y^{lf9je#iB%|L(7~ z{CB@W_q(0Rnd#}lQVUj{5tKc2D5|(};_OBI zJ0EEOeC{|icD`)1THX;hnzP^}t54EzPFy?5D0b|HiB*%ha`PfUv0Af{ghr; zZ@GNvpU>p&w=31}ADR3l_e`yHfp+8DqO)~{&r=P0_Sf|++WX344o_#|48I$3p;Ffw zHq?Jzcjvc#EWeDg&z(>m`<#xPwRbk`<^A>KP~o<3e&^1`&EeE%&T}_bQefseJ$GB? zrdevL^}SYgpAHA#Tb4K7`bXimm+PdM+?lqh=7bbBOK`;0aoRrY@~Av}(XxzB+uhq;zA=UG9kux0pK4 zN|musa^7}m3*(AAQ_ju^vAk$^O!hU|LBH3@iLCu17F~F8&iahckyqI= z4Sba%&fa{s`&^k`$Mdc?jB{TeJ|pqmb<&!T#w#uNo>MXSsbxPaUVZw@q+Ji^b!HrV zEfM9?Uwx~r_QfOlA0G8mQ}@LhxST0_y(7otiB7EQ@!tAvV&xBX*d2qk?e2%isZ9QYFAM#HF`IcwyN?}R47xZC% z@g14l{Qkxozne-;q~H2&>&u^Jn&LNcjkcrG;S+4)8WVJ8xJElKuv$3fRQ=(r(iX*P zO?Fd`N}pR`-iUdhd$)(Icfjd&9{yM_1OZ<*vAzKxrnDZMSa zE6k8|*y4_psZf7K+PUQ%!G15;e`g>1Z>@Mx*R(IEIOGJ2)!ZdB4sO|5&Tdh7&gP4p z`%X4yt!42(!f8j6l%m&)v6zWJou^yhCG~h2hhoPfCeaY5zdKIIet53>#eo{w%_TAoKn;N%PTaxehg5caGIc^JgT(Z%-w`ksa z1FrglB5_~K?oEao>o*(-X0Ts4-D_f9k?c>0gl(HnJd|jeEWWERJW-QJXl2%E>!0s# zF0Pz3e@*!0)6XNhWunt!*si~|iaMb1Gi|RKzklM=gs*jLS4eI=FhyMG_aS~;C)G|D z&G3h}*FMQ|%?paVJXMQjZ$sQ+k&wG*4@e4J{mAr$zkWBv_p2(0xL5tXaI)@c)wDS| zGmeOx8>`*aer~Jw_+Pup-yH>;5{#~%Y+8A^X~`j`r7PcTpZxlyXp`kl`FUsRtamER z^SI2R|0KcOB=1DH`tBCyQ}weSdsR$|DUeRNF!}6M!xwM1|DGnkrt@T1pwHwxal&l+ z;c4sQPC5m+>{Gvgp+4)*p%b^)9&)l_$~!OnV4_j1s$|scgREBz`Z*pv$euO#&!*Hf zS6_Yn)O_pNn&!x_Dy!DKs}GNUp=IBgf5WkmGklff1gF<3+U>U={uQ}a-WcEU^u+AV z6OTj+tv1y8<^0gp;8%*Sq+7Vbfo*Y&)0Vq*3BC_1>-g|7A=u7yk$pm6{fmlTsXlS( z^2*A(Q~%cMytfFMKC@C@+gtqm{Dg=N>E?#~TMmaG*(`pv>qp&}*@-IN5_uDEtX=cj zqV>e&4g3Yn3hmZa2P>}%{GYt!#HDRI^TLetCN^8LF&}i^Kqr+TXVR`g^A6`o}?Dwti1Ouin5p%h5f;_VnMgWjk4P ziu2Xxb02>(?@@%sdKspQ>|Jqt)q>Jz|J$Ar-ySNM*7IZOy2;rmr#&?L8MN$g>B%ko z^R`u8%tn1eIZq&NEZjSMV?ne?SZjo!2 zepFheox&2}_+V1N(n{`-+Q8)C_s@iQ^CsB&c4cf|ePcnC^QqbKs@fV4KCOM7zeHlI z{*m_wy1Y-az7N{DZcA7T<4^5t@yE_?%*~hFdO0sA-nE`-QGsb-)Rclv3R;&~r=9no zzT5xslls}ya?~cAEGc~-#lQ6Cc2n!FlHb|Vl?=UgXI=#FT72M}qJ)42H&?aCRk6R5 z)lz-s4ydY6ne2CnPiy_t(J`o-&*g5DI1PPn!?lp#|#mUY6l_n}jllr)PvY@2hISH)E-RQ2pK zUbmQslUAk|aNK26_{W?bBLo+w#FbBvzHFMAD_RWM}=qt8oEYy(vEm z3|BFP>z&iNv-`B}+K6kn-gdtZQJI~&CnEkBOXcplix+zQD(flVR1&mZeNtTfMn>Zz z!#T36j{Mj=QzKaHPudmM)e2IKl4z&b>ih1 z?cDfq*;T5p@x_i7(i&T8_li~b|5~7->37L}-FpL(z`cRf?=Js5`SRljC%^0O`}>~T zy}rLkbA?tI#Jv_^UugwTPEOAFHHlXR1>1XTYQOi|?E5^?<{wXeFOPTb^od1rQ{~UL@i;|DclfY2 zH@{fCnM09{`J>DGMSGSN$*vdBk@OM{i?V(({mKm#h(qGtB}m1dvUKQMQ*vQW%f_dy>xOH zEuR-Pf$e+4u3YuEHvd~y-2yeu?k}qfe17h#~U-6QRNCxg77 zU*lzK?mD1xMZb5!veN3_dZ}4Cr}d{uHZ$M$ z{CeZTTmBP$(SZ@X@1*=zsveS#_FS;Xcz9>yEO-9^Hzz@ zoA!3zQ|sWreVK0*XU9xfrK;lcb!E)HZ5G~7`Bp?9t{)Q zu;DJd=OAy<(b~2-P{aLBl7b|auek&^Z%-BNlUz8(XNt1Kzln8IpH2}~iQv7_Y?`~! z-fV&1i)|VbZ~i~J*l(`>Uj3w0O5(Of{HNIM7yGWum=^HU{%U~kp+gfK-(6d_S1YQS zC#=sp;zq+Krrd6`&?gc*rGvk0%v`L&xy1guuw#AD{lz(Ir>FBe&fd3Ti{V2RzE7PS z^jnSC#HU(zt=oCd@V9Gi?z!MT`Ka|=dHY_?6SCbr<=SHQAf3<$qGp?4YQCK^VUuFh zjxPl|Q#{;W&pO4%5aTiLv)I;4e;I@L@9>s0{=D4%V%u5W+bg8zI`HxQoN#jUhrNk* z`O1!WZTa-9D(VmLAHB~Ty5zj$z4j>0bLt9GM~!`E6!HswJEj)3>2=+1VcXL5*oN0u z9c#aDxcl2yR7__-o87Bz7GBds=j&=WrdY4h>0R(Zj^(cY;~UE)G8CVjP}e=jz`r?V z^0DqO|9LzFf}$r+j&rd#Jsk7I!X#_z_cft)e>I)2rDWcJDOT{i{_A5qo26^#MzM*e z{66<1E@-K9SLfAch0UISO`C77sJ(hvvDNke`LO#UblU&)<);d#x=tA&m<&n%JjvhMg8o}db_@9+9T~B6W(yIHS-tfVN$W+ zs$MkpjqcLp|G84n>t6Z!zS+e%i8VuV>#G{;7plMA(+>JaMEc*bnCVp$wro|leT7ga z!<)0=tKxr$O#Ck@sbzj@N6+qA9d$3{y330t_a7BMsX5Oh=I%{C2JS}biV&qEFYB8H z+7~gWu!(!FIqLh#z~IbfzIjs)@-zPHR1KfDS9<04+U~CfQc@u|Dh|XgOl6rQb-Q`` z=Lzv#*XOxRb!MEn=3VdN@}S2-wv3AFN>w{_OJ8O&Dtvqz`UF?pErOQ6l@2bsynpx_yX1V7sCW%1h%+1Y`E1l{l z`G&9^{qw;*x2IIo?981u#(O&r_%qjK-;9zy=)bEicjIEWs!h5jQ>071>dPN5cWSo| zGMly5Z@IAG#T)G=kv`E~KU3JH9=TgTXpqTt&3sYfKcnSj|Mb_{k$>m@c>d*I{NDfJ zFaMYRcu-$(qxQ!J<2PU1`K#RT{a^k4zt`XWa=pv*pIckj0N^;>(oM(>aRPnH~BU-5OmY|G1{ZB8@#ezbl+GPNf=<>a1kcE7GZ z|GWS3PkW7d|8494{nvZ`f8p;x^%ftF@3;T|@~8cqzUQw?O1YWp7d-p(zO^F(kDJdHS@fVsgntj)W&Zpwo4^{+BY;JO*(pSFn7`mD9HH|(-XZ@1rh>BgF?`P1h8`}}GC z{!M?LCwxdKuy|o3^QDiiJ?>xqp9)>dfEi-J$HH!Y5bU4`_IE}{kEU8*uQcfw$0jq zDVzO!#k7}Rhdabq9buQqD`I+exc-^dy>(MPTc-1W`+Y;haZZ_qAO|PMwU;gbW7_Js z)u-HB7@1u*b@98SSL=ckGn?MU-Q4_CDORoioZ%L0mb&?uRJ|WO?9!WjbkcxN%qn90 zcw56|x7t5Gzp&WpM+7JMM!!_`y1Tw;w_Nd)i2C<03*HFm9}VQoPT0KqzQqZiJ@-nB zF79=j`8wy2>V{9Y+7DjV`~Uy1`m$d4zwH~jieL9H|DW=&{)TKb`}*C}|MOKf?^FH% zwtTm(|NnZ~_xdDJsqdUg>xC*!V8)^wF1}Z}(g5w%8uu=^vjtFUYr>95MBs zRS)+@Ejz(&5-(qS2>rRS+Pg0Ov>@A-J^Z`4l{OzzxP8g-^+rPQ~@T9Jr+n6Q`tr6XP z_HeO?&buA@rlQ+EU1r|?f=^8EZ^Bl#^Fd;@N9Q!9@6tb*BAh<`-4E5Tavrizr?xwH z&bju$FF8g?DWLTT=hd8dneHMcLi0KPGuY_O>O14QK<;C;_GQ-&%wEqeKDqwY_pLnY8g<;;>lSZvC_XYZKK6pKd&llgHwtf^eB$BW zSnSeJ>{4IsQfItq-`m5BZ6I9-XhR|7ZPVzk74s{rUg@{aOCJzMkj1>h;~h45rWjKV&Yu5&bEC z-@m^<{~w?Kzxq~P$+5l_0>e_!70mXGUtpC31;w%*3h_|%WW8n*vhrw@FWpPN;_o3BQ{T{KtW zz5T6PDf2gzXXeMuJpab{A9IA+GTE<<410e)y!mlPVQC}FB>5LSHujZ&EB@H4r>~#4 zmmz-t-S2np>UsT-KKo;_bYtZ*P4OxJvMV;GyRtt&rWpQl_mh;F`F2}e_EZ*FU2dB( z?c_4qGv=$`?vmY*%esftXPr={&so*j55g?#{^(a!^Xf9bu3}`0oM-)G`vQBL4VU$U zU$#|ji&$%>%d(e$!9?TZUDIzoIxGC{`<#TbgKm9YpPon9y)SpI|M}VJr%C(fn%t?3 zXX6~PP z@EYr+c{Z*+uXY8h-aIq;xlVretULufTW!0OISZ{G+%DvDDrIv$`c%nL!tm>bxfg2% zGiE=#l<@b2;6{e1^P#pm^Fr#)CI}Uqsl0KpD)(0xc6?ndZ|}Zswz%9q{**;p%cNty z-`_fzwoD{;*2EyjJ4dprkC?h`N?f6QY2l`&v6o)S<|}G%JhJ+f+CIklrN&o&$?&u{ zC#D$3>P&r|=Him|adjxqRhKHa(2~ccdrtn)IoH6iGAG(_>rp9@!uMt=IXuVJ>krNK zb-HuYW6K6fw>L^z5^jz~_jVVk6q`Ih`Imde^u#61T-S{pc=delTc@;s`pRLz@0D1v zopFZZH8p-U_BD6jO#0l+oxOhX;@ZA>%);NgNdy zMenTa-q`&jELW|5&8Ma#p_7!8l@~tuPf@66l2ZteYExie+Q7Xi;$Qn(zgjj?sXR8- z>E}b)*@X>{OkKCVI(*f=HL)u#risYM1gs0@pSL2*X6vzw_kv>lrX?6_+)m6}BVcHp z*u3Js^-GbBt{2+gE;`||eRWR2C7tBlvvQpJ4GY#iox12>;M>z1?(Zs@wB~BQ-2Ay* z*Bjj3uhg3=Y)#Z*Gx8G3JHt>t=|atvIoNW%{wL`v>Unf=mIN#v?$#Zd)et5X&^*>)SOFP*T z=)G>%+Cwk8{-4`Z!TF`Kymub=LZ`*-`byeu!@-apq**RTBZ{b9v4y~juA zo~}R0*rNOYEpJ=gzu&Ac>+2=sH}0z36|uKhTz}nU-sKk>O^;OA*Gc~Te1HD``lX-$ zC%%8kynoIAzUTFme9bibO)j6j|Ga$Lzt!jJcf84;^MCKdhZkPg*I)lReYu^*-~Q*F z@e=?3e1HD`{*OQMe0%FM>0Ki_}$zxr_8`QP<_V&}!B-+1{e^@054 VxHfH`<+cChMVCwTG0b3Q007$CAV>fJ delta 33113 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 diff --git a/packages/raw/bit32.tar.gz b/packages/raw/bit32.tar.gz index 76cb78b6ada62231efa070ad953dd0835516f4d1..e03b9124402f273f9d556f7bfd5b66e0758ed13c 100644 GIT binary patch literal 1094 zcmb2|=HPJKR-eW6KPj`s*hsG=v54Vq)cy6h%tW49*0(Or6xyP4gR`+(+tBx}$=8LU z%in%nHI>I=`W8jEzMbBtYwN53Dsw6dttr3b%pb-t+}d+J$8A~o!wRWKue0@4 z79@2lwY+7n*-9vC6&w|JAIPI)MiVvKS98{N?me_51z@G4o!P-~anx z)8<0`h5ycfkF$K)@BGVud(lzXXD4IkW&WRkrQRs-#eVy_59AI_zw=-A>i_WhWAbJ`c#lzr_+Ocw8Fmhf7cG7k%k3e@ z5_IwU#v3bUHM%sd_tn_s7h8RJ>o>QpCtrFzTA{GEN@-_OX6f=J^A|tQ2#)mrBvti` zx2nu$jnT%`0%P7Uv+f_8C3!#P+9QilpR}D7#k2H&&wGCL@uEj&m;GI5zHJU%Q@_DY zbkf4uT}OZBvuZhAO}bJnqV2%HPw_ol^~sOzN7uN|FR4w5>Cthox0n{iYy0F`bDZ$s zS3&7ftewwNvlC{qtnB>YxJWv4t=yh}8k=sPQ4qgB`N02@dsk*`UaDI^tMa#vvF7jX zo2M4-TtE9aBhd^JniXQY*%zWi_7_bVeO`WK~w)|q@CQP`%!0llirz2 zhJV{$tgp}vpVq%KB;-x`)@rWjTX)@xIg_^PV8F%g&aq2Z9Tz@n#u+=q<(_Rrqwkej zY4UH~?!P@U>-Z$MuMSx)Q}@rh_oDOL^@Hmkh1znntDbcf45($;Gx5+*{yG0+p8QFd zI`q@O{ak&-Hi3_B;(f+{*x%gy{Qp4yy#GEYSkBe!HBNuFCf!+F{-v(5{qNKDEeG#4 z{Nn$*fAQD*>JqQ&%U}JM6~0-S^*{V-z09Hi`{g;09F}X#WxxRbeDMrtZ`8eH2w-3U E06)+^6aWAK literal 1170 zcmb2|=HOVnCnJmLe^O?Nv5{U$ViCjJsObL1W+LZ|_a6!h)qJVOA}wvC?HiiAI!nIn z>Z)3qw_bjad~T=;NT#1!l~rGz%gncP!pz*+CDxYrog13p79V_W{oscD@5k@!o;}Sz z_}uB+xuyk9*9|!i6;$Uvu~3ls9&mFvgIVjNpw;hV)jfK`v?4pBW&Aa`J!OpSISkcq zyk?wdzpRt%x{e%Cy|AU>J=ldBfKJY*M$p4zf({}3Agsw7vTJMr+{y#bDv%Rw7)tH7z zflG2+dNcorpZdSver>DIr!&=?A5P%C-mbs+-{r%<{1^O-U-Hj?+gJNNiROUU$1!h!(aA4{2;hPGCQr?*DTm`-a?(}tLrR3OlT9yQZ^1*w0?D>&BU{|`6f>H zpWkerz?C}tYKX^@qQw%LcD_gdRcKw`-j#MFXmxJ(3aQnnl9VH!2&w)ul2FQhY_t7P z?&+2LQqL&*t$R1AJj$Y!Y4M`?MS`>VF6_w5c#~(jgiogMnRL9?`fsw4Cu&k-19LC; zZd*{g_uBOzThvc3GK<>olBH=>zT9xXi~faMp3;wb&wR-Ka<*{$tOI7}?n*5%|5=-) zbNafg>PMUBljrLF3t8@V|NGx<@iF(rpRLR&{F<=kYJ8~E+exOo1Er_fUn^kSc{1bJ ziu8t;HSPC#%bJ|qzOHbeU$Q$r=zC68y@gm5^W~@Snr8~vmS-ugo$GS>SyqC+;U#8P z_QreMtE)deTi*Asj-~jgKhqD_vgF1g)4KljAHw;8EBZ#_L5+kX0B=Dm&A zLQ`(eF|8Dokp39_w&=>I*G7>m^uj#3i?_$~1)5nTtemxqXY$_jeY>@-f34pU^{dyMhJEx22`VQs~_)U^u?ivz5$ykm%8a=zp*`?vbP>96g7|E^zrq5q8C28l^; zyROx{7*0NUOQg^E4P$l5|8S2x|KhW*H5qn4lDJl{*BD;5HvMe6{Lj4`*8e@*XK;dd z#s3fg&zt`Jzxeh3Wr@$)OPo&fwu(2bUiqKjN$mN`zy7QKGiJZCKm6;?yZ>$f>-Cu4 Yu-7qUGGKu7eD#d~U)23z2w-3U0A`X~n*aa+ diff --git a/packages/raw/blake2s.tar.gz b/packages/raw/blake2s.tar.gz index e2b717eeef5625536d2dda9cea8beede2cc9a641..a367258d738b905787a96bc36dce132e270d8926 100644 GIT binary patch literal 1607 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 B<81%{ literal 7735 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 KpqfE~kpTcaeMJ!f diff --git a/packages/raw/deflate.tar.gz b/packages/raw/deflate.tar.gz index afdd204e38b7e632f121e71e21c8c4e8f801a48c..6ea7c59711a7772d1d41951d2ae16a271237ff7b 100644 GIT binary patch delta 27506 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 S1S3xMFZ=oHa;^*pObh_P`r^g_ delta 27645 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 diff --git a/packages/raw/hysh.tar.gz b/packages/raw/hysh.tar.gz index b5fb772602ab8249fc771346e2198280a61fed63..74a37a44dd671aeb1643c46617f93a75d6cebc91 100644 GIT binary patch literal 28385 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 Q{sZX=YvO7dE-*0w0E}Iry#N3J literal 27951 zcmb2|=HOVnCnJmLe@10-hF(cx5yP9kud8mGiD_8v|I789-)@(kXtL+DC((~wW-jTx z{A~7}zR7RS-K5Rem>ifCJWl#O+9sU2Y@-Vk z_W`C2c@Yt-cVE0)@#Wa=KZ+mzDEz%G{`1R^Z{HbOcl`O^dkgG;Nbml0Tel`H z^4-!4f9~%)cm9Fi>?aRZB)*lu&&$ov%gej}HZMOf_x|l&yFYDz`h5St;;N~0^J*TN z6$HP}%YS_T-@7vZztL}g{`;1&VfW6vx9{C+{cC@t@p{g0v+w(-Kg|@X-WVU8cklQ9 z7t41q`S1NJ{?h-o2d|}-zkZkY{@t?#&;R?ye!V~Y>9We%T|ZO*E&cZY+_f;vgc>m4!{6GCm zz32bw^KUQufAgve*W=A=etS+;bGyd9Q~?(`^TTTtp|_awBUQ(`{v3` z;rPNx3vK!7zmr$~*ZuiF{P=%%1Mb`2|NdY7P=EjQUi}J=irT;V#nsvAEC1`h{6Fd6 zf5$KX?NXNo6nXb<92Ynq_i(ng!S|tIS&E_erg9AeNqyup4`A2SvK|H`W4ke zPu}l&vu5d^d2My4OLs>ET#nv^Rh%nCf4Wu$HR%v`x*4~_q-I-XLPvu-1$d!i@}0YS(dtGnG(-+ow!O4-b~(X z!RvO?Q|6y^z$wQK`LZ>YeyaOQW4IaA{nxu}WD8$f$3o9e*F~wltZxd~?G+HUoaGPrsNd`I`S8e5BGIe&OGXEl>aK zxn>y?9sgR!avkr+#BVyE{6cR0I5@H8L&1f#)z6Ezed$`9WOt}+MStMzsTT!*?@jaj zV%XPrCho+j=U2Cx28sx@&d^B%-3sJWZiuzK3Z z5T6z^&ba6I`>p>AFFQDceY0=wku9HhC(dEbymyF~UAjwIdUxypwJUDCyX2;OpxgAf z-Dkfh+q5;e4qwl|XIuaG7031`Rp}?>_E(pGm}Xo3FG+r0N2oS~jpf%z!hVGkLbE

    )DP^^%rMVpmct8; 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 Y-L%P1?B#gwKL5}B*}tHOVFDuq0KEMfSO5S3 delta 15060 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 ICNMGp0Pf>S$^ZZW diff --git a/packages/raw/pid.tar.gz b/packages/raw/pid.tar.gz index 72636294397d8932d1bf0c137594257a94463c1b..19b3f19e33bdb23d1d87aaa215ada8ae004528d5 100644 GIT binary patch literal 1341 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 GU;qFPWzDSs diff --git a/packages/raw/spm.tar.gz b/packages/raw/spm.tar.gz index d3b9ba0e8af057d4681c55c2d4a4ccc4ea5e43ce..0c085595521096e6930c44afa74cc6948420e188 100644 GIT binary patch literal 5885 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 literal 1335 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 delta 1795 zcmaFP+svmY-_60Xc27nY)BlphBE6EtB8Imyuk&x437k*=FWRz;F=+9rNo(3=&m3+O z&0rUqs3%sh?_D;jtZe%%c9U%so?a2S)gZ~$t2=|;N`7^g}%b)Ku>GuC_n;ot{U7~yZ_@8o{ z^Sc$EX@36i^YQ=FyVI5h3h~$dGy6JO<@NqG|M~a-x9m&)k$iu1ZRG#+OaHYy%E^2d z`Z448{Pz$3=07JR;o@sIW& zsrOudxc*Fw^3(qZ&;Q@`9kqD z{=@xpAMbDf)t8hS@n3rqYEtbd{#s#qidWFDaKWV^p|1j6r3>6Ph!)iRF%dZ5tu*g> zpwQ%8fnC$q9=p}Ru+&8V(u|y@n$$CyTf&l!R1DTnT>isoLE(*?iZh=x8oW~JwhP$D z`~1WM7lS$x{a)8ehvu#Nw0EVzVFj&ClhTh|`rujbDKd8p>xmmbwyyj#Z%2};e{VDI z)8(&J_TOG~%zN&d#Xpv59$hs}X=${m`PG?T&1}KBeM;fmJ=tytTzFBtL9fNjW5?B3 zTH0x=mI^=6GF>4t;l`}Hj{CT#$2>Y$z`#{cdfNIv1*N} zx;nd>?*9Wz-X5wiEVDfA%b}K8(DO&leUfBEPDt+bvk#RtmM-#2K6g|%>pDlXJNGlC zN$WFWZgza`Z{^Jr-{zC@xJ^#xSdjdmi2142%5xjGbagI1E1_fdz+`f-gTN$?c{uQY~nq*B1_i#K3&1Yb*Ph6qq%6HGtX~Q40 zrQI*KNp6YuaG22HFTkL`sO$R-ap!3+JFcxb%*rXU#!WkWvtS9+OutScx0RQ+)ykc@ zcBSJ{&oayDUQfh@o8~VUF6e%wwX|%h<^7i_`?{_vb|wksHfx*>DZ69SSuFKD>hcMX zsgH7|p8K-q==vVt>ymFh_I1=>D{(K$)6r>8So7>)2B)i}jgR|Wn}fOrRU*FD8`ySA zv1!DLwh8dQ(B)g2W6Zmuaqr3@%41>ZSUw zohlJzt)P^WUJ2tLA#D37EvkNI@?X_ z)?Q3G{`ioI<1wCF0pBg>mW$lGI754e8fS5Rl&p)+F^f4@7+ZEUFYaAvq&V|<;e+7( zyR8Nl?S|}))1OK9TjZ)=e&#ys)7pSJW&)fs^@pY<$KG?5+t(^Ep>S{Ky>A6NlNN>i zm0KYE=*>~9hbr67JYe_V$m>#HUC<%8Xy`^`&e zXKy^w{*Ns`@X&0#>zhvS2geD`Y7F|mBGhQ}x6M&kSC~IoBg*ETZ+`o0oV7~St*w(5 zzR6hl_0q4#RTupd@7v`bniIjxyVUg4me_x@J6QV@n*QDP06m&j8QulD?STOPq#Dq_vF%!SKhT3h7hpg$=bXQNpaw^qe$laK$J zGIxTyKliPCyNRYf>o-T;5K~$*IqT}mck^P7hyM3l$LY?u|8d@*HCM8i3+5YWiN4Vf zT$tmtPsFGy{q=9Ldm0bwFBK@P;@9|HIcuZZ*NiMv!={7HYu`Ujoj#4LT2FfW=f4cM z51!g|^ys3f?>T1=breU4tgb$ORY=eE^VC&)eir}u7W7iLTen11R6hQl{PUiq;yFph^Z3GghJ{}bR4@cEFaQ8_UzjTZ diff --git a/packages/raw/xz.tar.gz b/packages/raw/xz.tar.gz index 559c0de3979073b1cf6a037d0714dd489352e718..9345278119da24a8c93641d632132a57955028c7 100644 GIT binary patch delta 11023 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 E02@8Q!2kdN diff --git a/packages/spm.pkg b/packages/spm.pkg index ef9d1ea..f1640a9 100644 --- a/packages/spm.pkg +++ b/packages/spm.pkg @@ -8,9 +8,12 @@ "dependencies": [ "tar", "deflate", - "json" + "json", + "minify", + "bit32", + "Hyperion-core" ], "version": "1.0.0", - "hash": "26d7cf304ad0bc36fbfa80af1b7af957de29a6c233e6d8a302b2b562f78326db", - "tarball": "http://localhost:8000/packages/raw/spm.tar.xz" + "hash": "c2df5d0028987d76b9321ed403bcb370", + "tarball": "http://localhost:8000/packages/raw/spm.tar.gz" } diff --git a/packages/sysinit.pkg b/packages/sysinit.pkg index 5e8da6d..dceb01d 100644 --- a/packages/sysinit.pkg +++ b/packages/sysinit.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "1.1.0", - "hash": "379cae7a2c42b5b0c30476c7660148c60ac426664627c649060c8feca01aa33f", - "tarball": "http://localhost:8000/packages/raw/sysinit.tar.xz" + "hash": "69efe854e597e8f53caaa2d0c03d0d6f", + "tarball": "http://localhost:8000/packages/raw/sysinit.tar.gz" } diff --git a/packages/tar.pkg b/packages/tar.pkg index dfafd3f..e6d2f2f 100644 --- a/packages/tar.pkg +++ b/packages/tar.pkg @@ -7,6 +7,6 @@ ], "dependencies": [], "version": "", - "hash": "2549429f0686c88354b091cbbd0cd7f80148115178cb3e5198924de28c7da6f4", - "tarball": "http://localhost:8000/packages/raw/tar.tar.xz" + "hash": "328ad76df75b9a0bc55f4fed0e31d7dd", + "tarball": "http://localhost:8000/packages/raw/tar.tar.gz" } diff --git a/packages/xz.pkg b/packages/xz.pkg index 526b50f..30443ab 100644 --- a/packages/xz.pkg +++ b/packages/xz.pkg @@ -10,6 +10,6 @@ ], "dependencies": [], "version": "1.0.0", - "hash": "38422b0eb99cef1122d4aeb3472e705ba304f58713280449bd3a6a492bacd521", - "tarball": "http://localhost:8000/packages/raw/xz.tar.xz" + "hash": "32b0bcfa6c57158a00e2cb75b9f2f023", + "tarball": "http://localhost:8000/packages/raw/xz.tar.gz" } diff --git a/spm.json b/spm.json index 56648e5..94fa250 100644 --- a/spm.json +++ b/spm.json @@ -2,9 +2,12 @@ "packages": { "Hyperion-core": "http://localhost:8000/packages/Hyperion-core.pkg", "Hyperion-firmware-ac": "http://localhost:8000/packages/Hyperion-firmware-ac.pkg", + "Hyperion-firmware-addon-cct": "http://localhost:8000/packages/Hyperion-firmware-addon-cct.pkg", "Hyperion-firmware-ccpc": "http://localhost:8000/packages/Hyperion-firmware-ccpc.pkg", "Hyperion-firmware-cct": "http://localhost:8000/packages/Hyperion-firmware-cct.pkg", + "Hyperion-firmware-lua": "http://localhost:8000/packages/Hyperion-firmware-lua.pkg", "Hyperion-firmware-oc": "http://localhost:8000/packages/Hyperion-firmware-oc.pkg", + "Hyperion-firmware-vm": "http://localhost:8000/packages/Hyperion-firmware-vm.pkg", "Hyperion-kernel": "http://localhost:8000/packages/Hyperion-kernel.pkg", "bit32": "http://localhost:8000/packages/bit32.pkg", "blake2s": "http://localhost:8000/packages/blake2s.pkg", diff --git a/spm.tar.gz b/spm.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..837e850ff1ee92ac0ba780bd674101b7358b4ebc GIT binary patch literal 3933 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%0A(|G(?|{Ns9VeYdxn_T4^Xx%u~x zLN}g$-#_o!z5m8`lDr@Zm&TLwEAO9>@63)hdVWLdn6l>EU-#GjSAAb^D=WJ{n6Vv literal 0 HcmV?d00001 -- 2.55.0

    !1Tr1ZyE6AxR39XI8YU%SN4eC~XE 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 Nh6wr1`3x7B7y$FC(U#Cfy z507~kc=0XmYyKF!PorG+d?{~9_Lc)tCt6lN?9F@RsxjF_d871P_Bs)Z#S>+B2=>KX zX82dHv3PY0w~@_5iPm8Ez>*vPL+|n0^vJH+av=QQ`(JWq0T-72|7mUJwG&U`zMiq|5yC0j&uEA_@bSy=+>A2 zeXsscKigF>%lPx=2{!4Rvzz@(I6M9e{Fi>Tznz)q<9_dt_47`oR9OA5zxR3msox*| zu>a!!^*`vBeCvY$cQ5~+QYSy}*#G&<|3_#tyr?h#B7g7yo*Dnl_y7OsCU~OW{A+#q zrCI-W2MUCJxzEqcv;Y6r#?;>ZtF-ss=+Qmx^Eq;o(pS-=FP`gPj#+cl=h7Te*KPYW ze>r_>>=ar0RwtdiDsP;Di{5-I@2RrQJyi6wpyT9m^I%i=ohmu^bIjd#-eN!cyLN?d z>7sNiUA3zHjkBB*V_)xokY^pbE-X5(>EyMHRcltMX1(4%J)PZ?b!F+2X+^$fAAKjS zdp-4OQ^;TTCA_O%YlVq^f4kYSH1YP)mDA34Yinpde)Rc(Xl~Z#*{y#4cR9b#y(V2% z;KcjeD)92`cgM1GuIyMj^?yKi|J?o&6{M+7`ZM}^-j{zI_@aiY?*39}F3;_%b0N!(= A`Tzg` literal 842 zcmb2|=HOVnCnJmLe`a20L1IyHs$NNA5yRVAvH7y60?U0d$H zO}q3?bE=Vns+NU@VeG{%f4|-2V?1^I#ga)Y&sORcZ0O%#eDATqp1$ipzv$NePs zFkI36*Pkp}uJ`=Ef91dAXZtpvub+~{cD{bW{{{d5d;ibe&i*Uj`tN+z`_|Jx{;$7W z?-s%Eiys0*R{u{u_xacV_`3g>uRomkulBt^6Ub24? z$KO9sEhaCOS*bEr?eu1ISMT*sw;g94Dw}f3vnYB-esOVNNcRMvv_9P#OC)Eh2EAA| zA#ZWLb^q0jTUmU0>o#Xw*4)ooT$rWHyRJKA+L?>}nTuTZb+{)5r$~3^T#Dab_*rj% zR%Kqadj9O(^zBps=tU|R#;=&VcB1m$#;OaScTUi{FQGPh(armUS!QcHeXc&%W0Swn z^Ht(%$O+%AoBETs^=~qNU0`sfQTF8po|5fNa!niUGVX7P^{Xunh{`#bkZW=!?6+mr z%j>s;mC|-vWO(>L^;@&(cf~dv9UZkLr|lK8H`wbNuU_#qcI$WbZS&@=tE?$v3znF9 zUf8;7jh`jg?0LI|`ND7My*SAz8+pA^?%sws?=zMz?%s9%)=#%5H!P=b|GjsQ*~+~q zTB6d5?#@r%d_D43=fgkj&-Y(`ZvXqg{JZMA6WHdIKKv8D`t$q~?va}eqQ2jG-*A54 zf7RLF_qQaZovZIT`1}5IBu2J!RqpPSXEF$6F$002zowVeO} diff --git a/packages/raw/installer.tar.gz b/packages/raw/installer.tar.gz index 5a6e1c9f3f33a65ed905ce6e7ba873e35713b3ec..bc088b0abad1af79fa06197c7a8f9e8840a611b7 100644 GIT binary patch literal 466 zcmb2|=HPJKR-eW6KQphmBrzu^wMefdv54XAEbqK#0})r-b6R^Eo9u72IW8@mmbl%a zYpH@@N00E*-THx-!nA&x1TmQIOJ`zIQQP!T%rX@BjBqV)-LK<^Sj2 zc(ZlAf6nnw_}~3c{L%FP!fKWabI$x>fA#<8@msq#txR9Pw%m8_byg!mp%wpE{8xXq zf0Encf9#?EyYD>znDBFd?qBs?iXC6&|M36!e^Rg8+W7zQ=l_e=Ja+t4Kl}gE3m@!3 z5@!F+Gr9h^zx@Anqw1F}H>QLZF8_1?S^e3iPXF~~{-56W-|~-r*Z;FSf7*YMU-7@c zf7zV>>QRaR*+19+sNeLj|Kx@LoM--Tt1W+etK9g%^?b%1uj+5!{(rsg;Q!+NJl5jX5n0uk2s_U-|jI(}MrvVSn#OUB9>g+yC6Z%YQxp&+_WO#D@-79zzB+ R@Idhg%O~M_1%?0y1^|j%{VxCj literal 521 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 F7ywBe=CuF- literal 3587 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 PP(6cj(KBa;3I+xM3#9R! diff --git a/packages/raw/lua.tar.gz b/packages/raw/lua.tar.gz index 20616723e3cec4d927921e75de5df26429192939..77ce892e84f35f419d67f8bf9bc5bb6aebeaff75 100644 GIT binary patch literal 2946 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 Z#)Sor&1`rX|0aE~e>HDn3qu710|0#!*t-A# literal 2995 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 Y643});DDb|@A*Ui$^B##h6)A-0JRJGk^lez diff --git a/packages/raw/micro.tar.gz b/packages/raw/micro.tar.gz index 0a1b5b59a156d33ba20a237a503f5dec93deb0a8..9340b974a704d03c9d9b1e477e31269022979ee3 100644 GIT binary patch delta 3819 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 delta 3916 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 b*2TWE$%g!5ynhxRt7k~=Ey-f2U|;|Mufm^e diff --git a/packages/raw/minify.tar.gz b/packages/raw/minify.tar.gz index 00f59e995e1ed5b32d57e5fd17ae473ed0fd7529..b379a792e87c36244ee3500fec2310b3d383284c 100644 GIT binary patch delta 15014 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