Compare commits

..

No commits in common. "main" and "feat/webworker" have entirely different histories.

138 changed files with 1730 additions and 2282 deletions

1
.gitignore vendored
View file

@ -1 +0,0 @@
*.swp

View file

@ -1,9 +1,7 @@
#FROM rastasheep/ubuntu-sshd:18.04
FROM ubuntu:22.04
FROM rastasheep/ubuntu-sshd:18.04
# Buildroot version to use
#ARG BUILD_ROOT_RELEASE=2021.02-rc2
ARG BUILD_ROOT_RELEASE=2024.02.8
ARG BUILD_ROOT_RELEASE=2021.02-rc2
# Root password for SSH
ARG ROOT_PASSWORD=browser-vm
@ -25,7 +23,6 @@ RUN echo 'root:${ROOT_PASSWORD}' | chpasswd; \
WORKDIR /root
RUN DEBIAN_FRONTEND=noninteractive apt-get -q -y install \
bc \
file \
build-essential \
bzr \
cpio \

View file

@ -1,4 +1,4 @@
# XRSH ISO
# Browser VM
A custom [Buildroot](https://buildroot.org/) config for a Linux x86 VM, meant to
be run in the browser as part of [XRSH](https://xrsh.isvery.ninja)
@ -15,14 +15,6 @@ filesystem overlay, and scripts necessary to build our distribution.
## Running ISO via qemu
first enable the vga console:
```bash
echo "console::respawn:-/bin/sh # vga console" >> rootfs/etc/inittab
```
then run qemu:
```
qemu-system-i386 -cdrom dist/v86-linux.iso
```
@ -102,10 +94,6 @@ If you need or want to update these config files, do the following:
$ ./build.sh --edit
```
this triggers the `make menuconfig` applications for linux/kernel/busybox
> NOTE: to save your changes to the repo: run `make savedefconfig` afterwards and commit `buildroot/configs`
## method 2 (manually)
```bash
@ -232,5 +220,3 @@ CONFIG_VIRTIO_PCI=y
Now run `make`
When it finishes, the built image is in `./output/images`.
> to debug (gdb access) uncomment the debug-section in `buildroot_v86/configs/v86_defconfig`, run `make` and then `./run.sh`

View file

@ -1,5 +1,4 @@
#!/usr/bin/env bash
set -x
test "$1" = "--edit" && {
EDIT="-ti -v $PWD/edit.sh:/root/edit.sh --entrypoint bash"
@ -11,12 +10,10 @@ test -d dist || mkdir dist
test -d cache || mkdir cache
rm -rf cache/*
OCI=$(which podman || which docker)
docker images | grep buildroot || docker build -t buildroot .
$OCI images | grep buildroot || $OCI build -t buildroot .
#$OCI --conmon /usr/bin/false run \
$OCI run \
docker run \
--rm \
--name build-v86 \
-v $PWD/dist:/build \
-v $PWD/buildroot-v86/:/buildroot-v86 ${EDIT} \

File diff suppressed because it is too large Load diff

View file

@ -1,2 +1 @@
source "$BR2_EXTERNAL_v86_PATH/package/nled/Config.in"
source "$BR2_EXTERNAL_v86_PATH/package/fusescript/Config.in"

View file

@ -1,47 +1,147 @@
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_AUDIT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_LOG_BUF_SHIFT=18
CONFIG_CGROUPS=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_NAMESPACES=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="${BR_BINARIES_DIR}/rootfs.cpio"
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_PCSPKR_PLATFORM is not set
CONFIG_EMBEDDED=y
CONFIG_X86_GENERIC=y
CONFIG_HPET_TIMER=y
CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y
CONFIG_X86_REBOOTFIXUPS=y
CONFIG_MICROCODE_AMD=NTEL_PSTATE=y
CONFIG_X86_ACPI_CPUFREQ=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_OSF_PARTITION=y
CONFIG_AMIGA_PARTITION=y
CONFIG_MAC_PARTITION=y
CONFIG_BSD_DISKLABEL=y
CONFIG_MINIX_SUBPARTITION=y
CONFIG_SOLARIS_X86_PARTITION=y
CONFIG_UNIXWARE_DISKLABEL=y
CONFIG_SGI_PARTITION=y
CONFIG_SUN_PARTITION=y
CONFIG_KARMA_PARTITION=y
# CONFIG_X86_EXTENDED_PLATFORM is not set
CONFIG_M686=y
CONFIG_X86_GENERIC=y
CONFIG_HPET_TIMER=y
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y
CONFIG_X86_REBOOTFIXUPS=y
CONFIG_MICROCODE_AMD=y
CONFIG_X86_MSR=y
CONFIG_X86_CPUID=y
CONFIG_HIGHPTE=y
CONFIG_X86_CHECK_BIOS_CORRUPTION=y
# CONFIG_MTRR_SANITIZER is not set
CONFIG_EFI=y
CONFIG_HZ_100=y
CONFIG_KEXEC=y
CONFIG_CRASH_DUMP=y
CONFIG_HIBERNATION=y
CONFIG_PM_DEBUG=y
CONFIG_PM_TRACE_RTC=y
CONFIG_ACPI_DOCK=y
CONFIG_ACPI_CONTAINER=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_X86_INTEL_PSTATE=y
CONFIG_X86_ACPI_CPUFREQ=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCI_MSI=y
CONFIG_PCI_DEBUG=y
CONFIG_HOTPLUG_PCI=y
CONFIG_PCCARD=y
CONFIG_YENTA=y
CONFIG_BINFMT_MISC=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_XFRM_USER=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_SYN_COOKIES=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_DIAG is not set
CONFIG_TCP_CONG_ADVANCED=y
# CONFIG_TCP_CONG_BIC is not set
# CONFIG_TCP_CONG_WESTWOOD is not set
# CONFIG_TCP_CONG_HTCP is not set
CONFIG_TCP_MD5SIG=y
# CONFIG_IPV6 is not set
CONFIG_NETWORK_SECMARK=y
CONFIG_NET_SCHED=y
CONFIG_NET_EMATCH=y
CONFIG_NET_CLS_ACT=y
CONFIG_DNS_RESOLVER=y
# CONFIG_WIRELESS is not set
CONFIG_NET_9P=y
CONFIG_NET_9P_FD=y
CONFIG_NET_9P_VIRTIO=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DEBUG_DEVRES=y
CONFIG_CONNECTOR=y
# CONFIG_PNP_DEBUG_MESSAGES is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_LOWLEVEL is not set
CONFIG_ATA=y
# CONFIG_ATA_VERBOSE_ERROR is not set
CONFIG_SATA_AHCI=y
CONFIG_ATA_PIIX=y
CONFIG_PATA_AMD=y
CONFIG_PATA_OLDPIIX=y
CONFIG_PATA_SCH=y
CONFIG_PATA_MPIIX=y
CONFIG_ATA_GENERIC=y
CONFIG_NETDEVICES=y
CONFIG_NETCONSOLE=y
CONFIG_VIRTIO_NET=y
# CONFIG_ETHERNET is not set
CONFIG_PHYLIB=y
# CONFIG_WLAN is not set
CONFIG_INPUT_POLLDEV=y
CONFIG_INPUT_SPARSEKMAP=y
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_JOYSTICK=y
CONFIG_INPUT_TABLET=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_NONSTANDARD=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
@ -52,11 +152,52 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_RSA=y
CONFIG_HW_RANDOM=y
CONFIG_NVRAM=y
CONFIG_HPET=y
# CONFIG_HPET_MMAP is not set
CONFIG_I2C_I801=y
CONFIG_PTP_1588_CLOCK=y
CONFIG_WATCHDOG=y
CONFIG_AGP=y
CONFIG_AGP_AMD64=y
CONFIG_AGP_INTEL=y
CONFIG_DRM=y
CONFIG_DRM_I915=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
CONFIG_FB_EFI=y
# CONFIG_LCD_CLASS_DEVICE is not set
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_HIDRAW=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
CONFIG_HID_EZKEY=y
CONFIG_HID_GYRATION=y
CONFIG_HID_ITE=y
CONFIG_HID_KENSINGTON=y
CONFIG_HID_LOGITECH=y
CONFIG_LOGITECH_FF=y
CONFIG_HID_MICROSOFT=y
CONFIG_HID_MONTEREY=y
CONFIG_HID_PANTHERLORD=y
CONFIG_PANTHERLORD_FF=y
CONFIG_HID_PETALYNX=y
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SUNPLUS=y
CONFIG_HID_TOPSEED=y
# CONFIG_USB_SUPPORT is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_EDAC=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_HCTOSYS is not set
CONFIG_DMADEVICES=y
@ -64,7 +205,9 @@ CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_MMIO=y
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
# CONFIG_X86_PLATFORM_DEVICES is not set
CONFIG_FUSE_FS=m
CONFIG_DAX=y
CONFIG_EFI_VARS=y
CONFIG_AUTOFS4_FS=y
CONFIG_FSCACHE=y
CONFIG_CACHEFILES=y
CONFIG_ISO9660_FS=y
@ -77,9 +220,24 @@ CONFIG_9P_FS=y
CONFIG_9P_FSCACHE=y
CONFIG_9P_FS_POSIX_ACL=y
CONFIG_NLS_DEFAULT="utf8"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_UTF8=y
CONFIG_PRINTK_TIME=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_SCHED_DEBUG is not set
CONFIG_SCHEDSTATS=y
CONFIG_RCU_TRACE=y
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
CONFIG_EARLY_PRINTK_DBGP=y
CONFIG_DEBUG_BOOT_PARAMS=y
CONFIG_OPTIMIZE_INLINING=y
CONFIG_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
@ -87,33 +245,19 @@ CONFIG_CRYPTO_RSA=y
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_CCM=y
CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_ECHAINIV=y
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CMAC=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_AES_586=y
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_DES=y
CONFIG_ASYMMETRIC_KEY_TYPE=y
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
CONFIG_X509_CERTIFICATE_PARSER=y
CONFIG_PKCS7_MESSAGE_PARSER=y
CONFIG_SYSTEM_TRUSTED_KEYRING=y
# CONFIG_VIRTUALIZATION is not set
CONFIG_CRC_CCITT=y
CONFIG_CRC16=y
CONFIG_OPTIMIZE_INLINING=y
CONFIG_VSOCKETS=y
CONFIG_VSOCKETS_DIAG=y
CONFIG_VSOCKETS_LOOPBACK=y
CONFIG_VIRTIO_VSOCKETS=y
CONFIG_VIRTIO_VSOCKETS_COMMON=y
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_ISA_DMA_API=y
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_MQ_VIRTIO=y
CONFIG_HAVE_PCI=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_NE2K_PCI=y
CONFIG_ETHERNET=y

View file

@ -9,8 +9,6 @@ echo "Created v86-linux.iso."
# Prepare license info. Start with Seabios, then buildroot's
wget https://raw.githubusercontent.com/coreboot/seabios/master/COPYING.LESSER \
-O ${BASE_DIR}/SeaBIOS_COPYING.LESSER
mkdir ${BASE_DIR}/legal-info || true
tar czvf /build/licenses.tar.gz \
${BASE_DIR}/SeaBIOS_COPYING.LESSER \
${BASE_DIR}/legal-info/buildroot.config \

View file

@ -1,4 +1,4 @@
#!/usr/bin/awk awk -f
#!/usr/bin/env -S awk -f
BEGIN {

View file

@ -19,20 +19,12 @@ test -f "$1" && {
OUTPUT=/mnt/run/$PID # com/isoterminal/feat/javascript.js writes output here
touch $OUTPUT
echo -n "PID=$PID; $javascript" > /dev/browser/js
# todo watch file
cat $OUTPUT
rm $OUTPUT
# check for file output
check_ready(){
test -f $OUTPUT && {
cat $OUTPUT | grep -vE '^undefined$';
code="$(cat ${OUTPUT}.exit)"
rm $OUTPUT;
exit $code;
}
}
check_ready
while sleep 0.3; do check_ready; done
# should we use flock, an awesome way to make processes read/write the same file
# while preventing 1001 concurrency issues?

View file

@ -1,23 +0,0 @@
#!/bin/sh
#
# this is a curl/wget stub which
# substitute it with browser's javascript fetch()
url="$1"
js = '
url = args[0]
ret = 0
fetch(url)
.then( (res) => res.arrayBuffer() )
.then( (abuf) => {
buf = new Uint8Array(abuf)
})
.catch( (e) => {
done = true
ret = 1
})
'
# wait for response filese

View file

@ -1,9 +1,23 @@
Welcome to XRSH
For an optimal experience, connect a (bluetooth) keyboard.
 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 . . ____ _____________ ________. ._. ._. . . . . . . . .
 . . _\ \/ /\______ \/ _____// | \. . . . . . . .
 . . _ \ / | _/\_____ \/ ~ \ . . . . . . .
 _ _ / \ | | \/ \ Y / _ _ _ _ _ _ _
 . . /___/\ \ |____|_ /_______ /\___|_ /. . . . . . . .
 . . . . . .\_/. . . . \/ . . . .\/ . . _ \/ . . . . . . . .
 ▬▬▬▬ https://xrsh.isvery.ninja ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
Open, local-first, polyglot, unix hackable & selfcontained XR apps.
credits: NLnet | @nlnet@nlnet.nl https://nlnet.nl/project
all FOSS devs | copy.sh (v86) aframe.io (AFRAME)
Leon van Kammen | @lvk@mastodon.online
Fabien Benetou | @utopiah@mastodon.pirateparty.be
Please hook up your (bluetooth) keyboard to use xrsh.
Use Ctrl+a+0/1/2/3/.. to switch terminals.
Use Ctrl+a+c to create a new terminal.
Type 'save' to save session (survives tab-close)
Type 'help_tips' for tips
Use 'save' to save session (survives tab-close)
Happy hacking! \o/

View file

@ -1,7 +1,5 @@
export HOME=/root
export PATH=~/bin:$PATH:/etc
set +m # mute job control notifications
export PATH=$PATH:/etc:~/bin
# source URL data from v86 (file created by v86 during boot)
test -f /mnt/profile.browser && source /mnt/profile.browser
@ -23,7 +21,6 @@ test -f ~/.profile.js && chmod +x ~/.profile.js && ~/.profile.js | grep -v undef
## forward not-found commands to javascript (via jsh)
command_not_found_handle(){
set +e
echo "[!] '$1' not found, did you mean $1(...) (javascript?)"
test -n "$ONBOARDING" && echo "[i] type 'help' for handy commands"
test -n "$ONBOARDING" || help_tips
@ -33,50 +30,41 @@ help_tips(){
echo ""
echo 'TIPS'
echo '----'
echo 'text editors ' "type '<cm|vi|mg|nano> <textfile>'"
echo 'text editors ' "type '<vi|mg|nano> <textfile>'"
echo 'programming languages ' "type 'ls ~/bin/helloworld*'"
echo 'upload file to xrsh ' "type 'upload <file>'"
echo 'download file locally ' "type 'download <file>'"
echo 'download remote file ' "type 'wget https://nlnet.nl/index.html -o index.html'"
echo 'paste text ' "ctrl/cmd+shift+v'"
echo 'paste text to file ' "ctrl/cmd+v'"
echo 'import file to scene ' "drag-drop file or ctrl/cmd+v or type 'upload'"
echo 'import remote URL ' "type 'require https://xrfragment.org/index.glb'"
echo 'reset scene & shell ' "type 'reset'"
echo 'run 64bit linux app ' "type 'blink <x86_64 binary>'"
echo 'js run ' "type 'js 'alert(\"hello\")'"
echo 'js console.log: ' "type 'console document.baseURI"
echo 'js function as cmd: ' "type 'alias $1=\"jsh $1\"' to run '$1 yo' as $1('yo')"
echo 'js inspect: ' "type 'js \"return document.baseURI\"'"
echo 'js console mute: ' "type 'echo 0 > /dev/browser/tty' to disable"
echo 'js capture console: ' "type 'tail -f /dev/browser/console'"
echo 'js<->filesystem hooks:' "type 'see [executable] files in ~/hook.d'"
echo 'say something ' "type 'say hello'"
echo 'jsh<->sh hooks: ' "type 'chmod +x ~/hook.d/*/* && alert helloworld'"
echo 'include file into page' "type 'require <url.js|css>'"
echo ''
echo 'type "help" or "man xrsh" to read the full manual'
ONBOARDING=1
}
export TERM=xterm-256color
export PS1="\[\e[36m\]> \[\e\[0m\]"
export PS1="\[\033[38;5;165m\]> \[\033[0m\]"
# aliases
alias ls='ls -ha -w100'
# interactive login
which screen &> /dev/null && {
[[ -t 0 ]] && {
eval $(resize) # important
printf "\r" # weird but needed
test -n "$STY" || {
# execute URL hash or GNU screen
test -n "$HASH" && hook URI/fragment "${HASH:1}"
test -z "$HASH" && screen -Aa -R -T screen-256color -c /root/.screenrc
}
test -n "$STY" && {
test -f /root/motd && cat /root/motd || cat /etc/motd;
say "welcome to eex r, shell. For an optimal user experience, connect a Bluetooth keyboard." &
resize # call twice
resize # otherwise COLUMNS/ROWS is 0
# add URL-hash as extra screen session
test -z "$HASH" || {
grep 'screen -t #' /root/.screenrc || {
echo "screen -t xrsh+URL 3 /bin/sh -c '${HASH}; sh'" | sed "s/'#/'/g" >> /root/.screenrc
}
}
screen -Aa -R -T screen-256color -c /root/.screenrc
}
test -n "$STY" && cat /etc/motd
}
cd $HOME

View file

@ -3,7 +3,7 @@
// do once (remember /etc/profile gets sources multiple times!)
if( !window['/etc/profile.js'] ){
const isoterminal = document.querySelector('[isoterminal]').components.isoterminal.term
const isoterminal = document.querySelector('[isoterminal]').components.isoterminal.isoterminal
const scene = document.querySelector('a-scene')

View file

@ -1,14 +1,12 @@
hook(){
test -z "$1" && { echo "usage: hook <cmd_or_jsfunction> [args]"; return 0; }
logger "$ hook $*"
cmd=$1
shift
test -d ~/hook.d/$cmd && {
find -L ~/hook.d/$cmd/ -type f -executable -maxdepth 1 | while read hook; do
logger " |+ hook $hook $*"
find ~/hook.d/$cmd/ -type f -executable | while read hook; do
{ $hook "$@" || true; } | awk '{ gsub(/\/root\/\//,"",$1); $1 = sprintf("%-40s", $1)} 1'
done
} | tee -a ~/hook.d/log.txt
}
}
alert(){
@ -23,8 +21,8 @@ alert(){
confirm(){
test -z "$1" && { echo "usage: confirm <question>"; return 0; }
read -p "$(printf "\033[0m")[?] $1 [y/n] $(printf "\033[0m")" y
test $y = "y" && echo true && return 0
test $y = "y" || echo false
test $y = y && echo true && return 0
test $y = y || echo false
hook confirm $1 $y
}
@ -46,7 +44,6 @@ console(){
#
# info: adds javascript/css url/script to DOM
require(){
test -n "$1" || { echo "usage: require <url>"; exit 0; }
file=$(basename "$1")
ext="${file/*\./}"
@ -64,12 +61,6 @@ require(){
echo "<a-entity xrf='$1'></a-entity>" >> /root/index.html
;;
sh|zip)
wget "$1" -o "$file" && \
chmod +x "$file" && \
"./$file"
;;
*)
alert $ext "extension is not supported (yet)"
;;

View file

@ -3,19 +3,12 @@
test -d /dev/browser || {
move_root_to_9pfs(){
test -d /mnt/run || mkdir /mnt/run # for javascript<->unix pids
mkdir /mnt/run # for javascript<->unix pids
test -d /mnt/root && return 0
mv /root /mnt/.
ln -fs /mnt/root /root
}
setup_clipboard(){
test -d /mnt/clipboard || {
mkdir /mnt/clipboard
echo "files appear here when dragdropping- or copy/pasting a file into the 3D scene (minimize in non-immersive mode)" > /mnt/clipboard/README.md
}
}
setup_links(){
ln -fs /etc/motd ~/.motd
ln -fs /mnt/profile.browser ~/.profile.browser
@ -38,37 +31,36 @@ test -d /dev/browser || {
}
setup_overlayfs(){
test -f /mnt/overlayfs.zip && ziprun /mnt/overlayfs.zip
test -f /mnt/overlayfs.zip && unzip /mnt/overlayfs.zip -d /
}
setup_incoming_cmds(){
# listen for shell cmds passed to v86 from browser
# (via isoterminal.exec(...))
stty raw < /dev/ttyS1
#cat /dev/ttyS1 | xargs -I{} /bin/sh -c 'logger "isoterminal.exec({})"; {}'
mkfifo /var/run/ttyS1
echo "source /etc/profile" >> /var/run/ttyS1
cat /dev/ttyS1 > /var/run/ttyS1 &
/bin/sh < /var/run/ttyS1 2>&1 | logger
/bin/sh < /var/run/ttyS1
}
setup_listen_homedir(){
sleep 4
/root/bin/watchfs &
sleep 4 # wait for inode of /mnt/root to become live (due to move_root_to_9pfs)
infinite inotifyd echo /mnt/root | awk '
# listen for writes to rootdir and send them to DOM
/^[we] \/mnt\/root index\.html/ { system("cat "$2"/"$3" | grep -vE \"^#!\" > /dev/browser/html") }
/^[we] \/mnt\/root index\.js/ { system("cat "$2"/"$3" | grep -vE \"^#!\" > /dev/browser/js") }
'
}
setup_mounts(){
mkdir /mnt/helloworld /mnt/THREE
fusescript /root/fs/helloworld /mnt/helloworld
fusescript /root/fs/THREE /mnt/THREE
}
modprobe fuse # load fuse
move_root_to_9pfs
setup_browser_dev
setup_clipboard
setup_links
setup_network
setup_overlayfs
setup_listen_homedir &
setup_incoming_cmds &
setup_mounts
setup_listen_homedir &
}

View file

@ -8,6 +8,4 @@ enterAR
exitVR
exitAR
tail -n1 -f /dev/browser/console /var/log/messages
require https://snips.sh/f/VBz-iWm8so?r=1
a-gltf-model https://xrfragment.org/example/assets/index.glb
a-gltf-model https://coderofsalvation.github.io/xrsh-media/assets/background.glb
require https://coderofsalvation.github.io/xrsh-media/assets/background.glb

View file

@ -1,2 +0,0 @@
#!/bin/sh
cm /root/index.html

View file

@ -1,2 +0,0 @@
#!/bin/sh
cm /root/manual.md

View file

@ -1,2 +0,0 @@
#!/bin/sh
cm /root/index.js

View file

@ -1,2 +0,0 @@
#!/bin/sh
say hello world

View file

@ -1,7 +0,0 @@
{
"speak_rate": 0.88,
"speak_pitch": 0.01,
"speak_volume": 1,
"speak_voice": -1,
"speak_voices": 0
}

View file

@ -1 +0,0 @@
https://corsproxy.io/?url=

View file

@ -1 +0,0 @@
echo "[$(pwd)] the project root-directory"

View file

@ -1,23 +0,0 @@
# ctrl-arrows jump between words / begin/end line
"\e[1;5D": shell-backward-word # seperate by spaces instead of: backward-word, forward-word
"\e[1;5C": shell-forward-word #
# start bash recursive search from cursor using up/down keys
# prevents pressing up-key zillion times in bash/mysql/etc
"\e[A": history-search-backward
"\e[B": history-search-forward
"\C-R": history-search-forward
# always show completion
#set completion-query-items 1000
TAB:menu-complete
"\C-d":kill-word
# completion improv
# for readability: put / after directory names and * after programs:
set visible-stats on
"\e[1;5B": beginning-of-line
"\e[1;5A": end-of-line

View file

@ -1,52 +1,19 @@
alias enterVR='js "document.querySelector(\"a-scene\").enterVR()"'
alias enterAR='js "document.querySelector(\"a-scene\").enterAR()"'
alias exitVR='js "document.querySelector(\"a-scene\").enterVR()"'
alias exitAR='js "document.querySelector(\"a-scene\").enterAR()"'
# (new)user friendlyness
alias vi='echo -e "HINT: type :q (and press enter) to quit\n[press a key]";read;vi';
alias mg='echo -e "HINT: type Ctrl+c Ctrl-x to quit\n[press a key]";read;mg';
alias nano='echo -e "HINT: type Ctrl+x to quit\n[press a key]" ;read;nano';
alias vi='echo "HINT: type :q (and press enter) to quit\n[press a key]";read;vi';
alias mg='echo "HINT: type Ctrl+c Ctrl-x to quit\n[press a key]";read;me';
alias nano='echo "HINT: type Ctrl+x to quit\n[press a key]" ;read;nano';
# save space in the iso image
alias make="mim"
# start index.js
test -f index.js && chmod +x index.js && ./index.js | grep -v undefined
# minimalist autoenv version [https://github.com/hyperupcall/autoenv]
cd(){
dir_cur=$(pwd)
ignore=0
test "${dir_cur:0:4}" = /mnt && ignore=1
test "${1:0:4}" = /mnt && ignore=1
test "$ignore" = 1 && { command cd ${1:+"$@"}; return 1; }
test -f $(pwd)/.env.leave && source $(pwd)/.env.leave # cleanup environment
command cd ${1:+"$@"} && {
hook cd "$@"
test -f $(pwd)/.env && { # setup environment / run scripts e.g.
test "$(cat ~/.config/autoenv/prompt_cd)" = 1 && {
if "$(confirm ".env detected, execute?")" = false; then return 0; fi
}
source $(pwd)/.env
}
ls # list directories
}
}
test -f /root/.boot || {
touch /root/.boot # make sure we run below once
# add menu items https://xrsh.isvery.ninja/#Launcher%20menu
/root/bin/launcher init
# start index.js if /dev/browser/js filesize is not great than 0
if [ ! -s /dev/browser/js ]; then
chmod +x /mnt/root/index.js && /mnt/root/index.js | grep -v undefined
fi
# start index.html if /dev/browser/html filesize is not great than 0
if [ ! -s /dev/browser/html ]; then
chmod +x /mnt/root/index.html && /mnt/root/index.html
fi
# start index.html
test -f index.html && chmod +x index.html && ./index.html
# uncomment to set location (3D scene file [with XR Fragments] )
#require https://xrfragment.org/index.glb
require https://coderofsalvation.github.io/xrsh-media/assets/background.glb
}
# auto-load /mnt/.env (if passed via AFRAME's isoterminal="overlayfs: boot.sh" e.g.
test -f /mnt/.env && source /mnt/.env
#require https://coderofsalvation.github.io/xrsh-media/assets/background.glb

View file

@ -3,7 +3,6 @@ caption always "%{= kw}%-w%{= BW} %t %{-}%+w %-= $HOSTNAME"
# skip the startup message
startup_message off
msgwait 0
# go to home dir
chdir /root
@ -15,7 +14,7 @@ autodetach on
defscrollback 10000
# start with visual bell as default
vbell off
vbell on
vbell_msg "bell on %t (%n)"

View file

@ -1 +0,0 @@
echo "[$(pwd)] projectspecific cli utilities"

View file

@ -1,11 +0,0 @@
#!/bin/sh
test -n "$1" || { echo "usage: a-gltf-model <gltf-file>"; exit; }
file="$1"
echo "$file" | grep -q http || {
file="$(readlink -f "$1")"
file="${file#/}" # strip leading slash if present
file="file://xrsh/$file"
}
echo "<a-gltf-model src='$file'></a-gltf-model>" >> /root/index.html

View file

@ -1,7 +0,0 @@
#!/bin/sh
test -n "$1" || { echo "usage: a-text <textfile_or_string>"; exit; }
str="$1"
test -f "$str" && str="$(cat "$1" | sed ':a;N;$!ba;s/\n/\\n/g' )" # escape linebreaks
echo "<a-text value='${str}' position='-0.4 1.8 -3' grabbable></a-text>" >> /root/index.html

View file

@ -1,3 +0,0 @@
#!/bin/sh
# simple directory annotator [via autoenv]
echo "echo \"[$(pwd)] $*\"" >> .env

Binary file not shown.

View file

@ -1 +0,0 @@
../opt/codemirror/codemirror

View file

@ -1 +0,0 @@
../opt/codemirror/codemirror

View file

@ -0,0 +1,25 @@
#!/bin/js
(async function(){
await AFRAME.utils.require({
codemirrorjs: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.1/codemirror.js",
codemirrorcss: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/codemirror.css",
cmtheme: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/theme/shadowfox.css"
})
await AFRAME.utils.require({
cmxml: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/mode/xml/xml.js",
cmjavascript: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/mode/javascript/javascript.js",
cmcss: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/mode/css/css.js",
highlight: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/mode/htmlmixed/htmlmixed.js",
codemirrorAF: "com/codemirror.js"
})
document.querySelector("a-entity#root").innerHTML += `<a-entity codemirror='file: ${args[1]}'></a-entity>`
})()
return "" // empty stdout(put)
// for shellscript-equivalent see bin/codemirror

View file

@ -0,0 +1,11 @@
#!/bin/sh
source /etc/profile.sh
require 'https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.1/codemirror.js'
require 'https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/codemirror.css'
require 'https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/theme/shadowfox.css'
require 'com/codemirror.js'
echo "<a-entity codemirror='file: $1'></a-entity>" >> /dev/browser/html
# for js-equivalent see bin/codemirror

View file

@ -1,10 +0,0 @@
#!/bin/sh
# this is a curl stub which directly interfaces with the browsers javascript fetch() via wget
# REASON: way less overhead / complexity compared to the v86 linux networking stack
tmp=/tmp/$$
wget "$1" -o $tmp
test -f $tmp && {
cat $tmp
rm $tmp
}

View file

@ -1,42 +0,0 @@
#!/bin/sh
source /etc/profile.sh
file(){
javascript='
filename="'$(pwd)/$1'"
res = ""
function saveUint8Array(uint8Array, filename = "download.bin", mimeType = "application/octet-stream") {
if( !uint8Array ){
console.log( res = "file not found" )
return false
}
const blob = new Blob([uint8Array], { type: mimeType });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename.replace(/.*\//,"");
// Programmatically trigger the click event
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
// Clean up the URL object
URL.revokeObjectURL(url);
}
let term = document.querySelector("[isoterminal]")
term.emit("read_file", [filename, (str,buf) => saveUint8Array(buf, filename) ] )
return res
'
hook save
js "$javascript"
exit
}
test -n "$1" && file "$1"
echo "Usage: download [file] # pass no argument to save VM state to localStorage"

View file

@ -1,2 +0,0 @@
#!/bin/js
document.querySelector("a-scene").enterAR()

View file

@ -1,2 +0,0 @@
#!/bin/js
document.querySelector("a-scene").enterVR()

View file

@ -1,2 +0,0 @@
#!/bin/js
document.querySelector("a-scene").exitAR()

View file

@ -1,2 +0,0 @@
#!/bin/js
document.querySelector("a-scene").exitVR()

View file

@ -1,27 +0,0 @@
#!/bin/sh
set -e
echo '[i] this is a git-stub'
usage(){
echo 'usage: git clone <codeberg.org/xrsh/xrsh> <branchname_or_commithash>';
exit 0;
}
test -n "$1" || usage
clone(){
test -n "$2" || usage
name=$(basename $1)
branch=$2
dir="$name/$branch"
test -n "$DEBUG" && set -x
wget $1/archive/$branch.zip -O "${name}.zip"
unzip ${name}.zip
rm ${name}.zip
set +x
echo ""
echo "[i] unzipped repository to directory '$name'"
}
"$@"

View file

@ -1,2 +1,2 @@
#!/bin/sh
echo "$@"
echo hook.d/alert/yo: yo $*

View file

@ -1,4 +1,4 @@
#!/usr/bin/awk -f
BEGIN{
print( ARGV[0] " " ARGV[1] " " ARGV[2] )
print "hook.d/alert/yo.awk: yo " ARGV[1]
}

View file

@ -1,4 +1,3 @@
#!/bin/js
msg = args.join(' ')
console.log(msg)
//alert(msg)
str = "hook.d/alert/yo.js yo"+args.slice(1).join(' ')
alert(str)

View file

@ -1,4 +1,2 @@
#!/usr/bin/env lua
local msg = table.concat( arg, " ")
print( msg ) -- to stdout
--os.execute( "logger '" .. msg .. "'") -- to logs (/var/logs/messages)
print("hook.d/alert/yo.lua: yo " .. args[1])

View file

@ -1,7 +1,3 @@
#!/usr/bin/env micropython
import sys
import os
msg = sys.argv[0] + ": " + " ".join(sys.argv)
print(msg) # to stdout
#os.system("logger '"+ msg +"'") # to logs (/var/log/messages)
print("hook.d/alert/yo.py: "+sys.argv[1])

View file

@ -1,19 +0,0 @@
#!/bin/sh
init(){
# add menu items https://xrsh.isvery.ninja/#Launcher%20menu
{ find /root/.config/launcher -type f; find /root/.config/launcher -type l; } | while read item; do
js '
let term = document.querySelector("[isoterminal]").components.isoterminal.term
launcher.register({
name: "'$(basename $item)'",
cb: () => term.emit("exec",["'$item'"])
})
return "'$item'"
'
done > /tmp/log
}
"$@"

View file

@ -1,4 +0,0 @@
#!/bin/sh
test -z "$1" && { echo "usage: pkg <ls|install> [pkgname]"; exit 0; }

View file

@ -1,6 +0,0 @@
#!/bin/sh
/usr/bin/reset
set -x
echo '' > ~/index.html # empty scene
set +x
echo "[i] terminal and 3D scene are re-initialized"

View file

@ -1,24 +1,13 @@
#!/bin/sh
source /etc/profile.sh
state(){
javascript='
const isoterminal = document.querySelector("[isoterminal]").components.isoterminal.term
isoterminal.save({'$1':true})
return "\n"
const isoterminal = document.querySelector("[isoterminal]").components.isoterminal.isoterminal
isoterminal.save()
return "[OK] xrsh state saved\n"
'
echo "[i] triggering ~/hook.d/save/* scripts"
echo "[OK] triggering ~/hook.d/save/* scripts"
hook save
echo "[i] warning: do not resize the browserwindow"
echo "[i] please wait.."
echo "[..] please wait.."
js "$javascript"
exit
}
test -n "$1" && state "$1"
test -z "$1" && {
echo "Usage: save [localstorage|remotestorage]"
echo ""
echo "save VM (filesystem) to local (=default) or remotestorage"
}

View file

@ -1,57 +0,0 @@
#!/bin/js
window.speak = async function(str, opts){
if( !str || typeof window.SpeechSynthesisUtterance == 'undefined' ) return
let defaultOpts
let term = document.querySelector("[isoterminal]").components.isoterminal.term
try{
let buf = await term.worker.read_file("root/.config/webspeech/settings.json")
let jsonstr = new TextDecoder().decode(buf);
defaultOpts = JSON.parse(jsonstr)
}catch(e){
defaultOpts = {
speaksigns:true,
override:true,
speak_rate: 1,
speak_pitch: 0.01,
speak_volume: 1,
speak_voice: -1,
speak_voices: 0
}
}
opts = { ...defaultOpts, ...opts, speak: {} }
if( opts.speaksigns ){
str = str.replace(/\/\//,' ')
.replace(/:/,'')
.replace(/\//,' slash ')
.replace(/\./,' dot ')
.replace(/#/,' hash ')
.replace(/&/,' and ')
.replace(/=/,' is ')
}
if( str == opts.speak.lastStr ) return // no duplicates
opts.speak.lastStr = str
let speech = window.speechSynthesis
let utterance = new SpeechSynthesisUtterance( str )
opts.speak_voices = speech.getVoices().length
if( opts.speak_voice != -1 && opts.speak_voice < opts.speak_voices ){
utterance.voice = speech.getVoices()[ opts.speak_voice ];
}else{
let voices = speech.getVoices()
for(let i = 0; i < voices.length; i++ ){
if( voices[i].lang == navigator.lang ) opts.speak_voice = i;
}
}
utterance.rate = opts.speak_rate
utterance.pitch = opts.speak_pitch
utterance.volume = opts.speak_volume
if( opts.override ) speech.cancel()
speech.speak(utterance)
}
window.speak( args.slice(1).join(' ') )
return ""

View file

@ -1,10 +0,0 @@
#!/bin/sh
test -n "$1" || {
echo "usage: tab <ID>"
echo -e "\ntabs: "
find /tmp/*.dtach | xargs -n1 basename | sed 's/\.dtach//g'
exit 0;
}
# attach to a sessions [or create if it does not exist]
dtach -r ctrl_l -A /tmp/$1.dtach

View file

@ -1,4 +0,0 @@
#!/bin/sh
test -n "$1" || { echo "usage: teleport <http://...foo.glb>"; exit 0; }
echo "" > ~/index.html # empty scene
a-gltf-model $*

View file

@ -1,13 +0,0 @@
#!/bin/js
// this allows opening a file upload popup, to upload to the clipboard.
// because not all input devices (handcontrols) present copy/paste contextmenus
// or file drag/drop functionality
//
const isoterminal = document.querySelector('[isoterminal]')
const upload = isoterminal.dom.querySelector("#pastedrop")
const scene = document.querySelector('a-scene')
// trigger file input
scene.exitVR()
upload.click()
return "[i] files are uploaded in /mnt/clipboard\n"

View file

@ -1,10 +0,0 @@
#!/bin/sh
exec inotifyd echo /root /root/.config/launcher | awk '
# listen for writes to rootdir and send them to DOM
/^[wne] \/root index\.html/ { system("cat "$2"/"$3" | grep -vE \"^#!\" > /dev/browser/html") }
/^[wne] \/root index\.js/ { system("cat "$2"/"$3" | grep -vE \"^#!\" > /dev/browser/js") }
/^[wne] \/root\/.config\/launcher/ { system("/root/bin/launcher init") }
#/.*/ { system("logger "$0) }
'

View file

@ -1,29 +0,0 @@
#!/bin/sh
# this is a wget stub which directly interfaces with the browsers javascript fetch()
# REASON: way less overhead / complexity compared to the v86 linux networking stack
url="$1"
filename="$(basename "$url")"
tmp=/mnt/$$
test -z "$1" && { echo "usage: $0 <url> [-o outfile]"; exit 0; }
for arg in $*; do
test $arg = "-o" && shift && filename=$*
shift
done
echo "$url" | grep -qE '^http' && test -f ~/.config/wget/corsproxy && {
proxy="$(cat ~/.config/wget/corsproxy)"
url="${proxy}${url}"
echo "[i] using CORS proxy: $url" 1>&2
}
js '$("[isoterminal]").emit("create_file_from_url",["'$tmp'","'$url'"])'
while sleep 0.5s; do
printf "." 1>&2
test -f $tmp && {
test "$(awk '{ print $1 }' $tmp)" = 0 && retcode=1 || retcode=0
mv $tmp "$filename" && printf "\n" && exit $retcode
}
done

View file

@ -0,0 +1,2 @@
#!/bin/sh

View file

@ -1,24 +0,0 @@
#!/bin/sh
set -e # halt on error
file="$1"
dir="$(basename "$file")"
echo "$file" | grep -q http && {
filename="$(basename "$file")"
wget "$file" -o /tmp/$$.zip
file=/tmp/$$.zip
}
logger "$0: extracting $file"
test -d "/root/$dir" && rm -rf "/root/$dir"
mkdir -p "/root/$dir"
cd "/root/$dir"
unzip "$file"
cd "/root/$dir" # trigger auto-env (.env file)
test -f .env && test "$(cat ~/.config/autoenv/package)" = 1 && {
logger "$0: detected $(pwd)/.env [autoenv]"
logger "$0: running $(pwd)/.env"
sh .env
}

View file

@ -1 +0,0 @@
echo "[$(pwd)] 'fusescript' filesystems https://codeberg.org/coderofsalvation/fusescript"

View file

@ -1,71 +0,0 @@
#!/bin/sh
# virtual file interface for THREE
STATE=/run/THREE
LOG=~/.fuse.log
update(){
js '
let fuse_dir = () => '16877 2 0 0 4096 8'
let fuse_file = (size) => `33188 1 0 0 ${size||1} 1`
function traverseScene(object, path = '/', result = '') {
const objectName = object.name? object.name : object.id;
result += `${path}${objectName} ${fuse_dir()}\n`;
result += `${path}${objectName}/position ${fuse_dir()}\n`;
result += `${path}${objectName}/position/x ${fuse_file()}\n`;
result += `${path}${objectName}/position/y ${fuse_file()}\n`;
result += `${path}${objectName}/position/z ${fuse_file()}\n`;
result += `${path}${objectName}/rotation ${fuse_dir()}\n`;
result += `${path}${objectName}/rotation/x ${fuse_file()}\n`;
result += `${path}${objectName}/rotation/y ${fuse_file()}\n`;
result += `${path}${objectName}/rotation/z ${fuse_file()}\n`;
if( object.userData ){
result += `${path}${objectName}/userData 1 1 1 1\n`;
for( let k in object.userData )
result += `${path}${objectName}/userData/${k} 1 1 1 1\n`;
}
object.children.forEach(child => {
result = traverseScene(child, `${path}${objectName}/`, result);
});
return result;
}
return traverseScene( document.querySelector('a-scene').object3D );
' > $STATE
}
readdir(){ # print first column [filename] from header
test -f $STATE || update
awk '/^#\'$1'/ {
gsub("^#'$1'[/]?","",$1); # strip dirname
gsub("\\/.*","",$1); # strip subdirs/files
if( $1 ) print $1
}' $STATE | uniq
}
getattr(){ # print column 2 till 7 from header
awk '$1 == "#'$1'" { print $2" "$3" "$4" "$5" "$6" "$7 }' $STATE
grep -qE '#$1' $0 || return 2 # FUSE expects -NOENT if file does not exist
}
read(){ # print everything (data) after 7th column
awk '$1 == "#'$1'" { $1=$2=$3=$4=$5=$6=$7=""; sub(/^ +/, ""); print $0 }' $0
}
getxattr(){ # print xattr value from commentheader
awk '$1 == "#xattr:'$1'" && $2 == "'$2'" { print $3 }' $STATE
}
setxattr(){ # save xattr value from commentheader
file=$1 ; key=$2 ; shift; shift
sed -i "s/^#xattr:\\$key .*/#xattr:\\$key $*" $STATE || echo "#xattr:$file $key $*" >> $0
}
listxattr(){ # list xattr keys
awk '$1 == "#xattr:'$1'" { printf("%s\0",$2) }' $STATE
}
echo "> $0 $*" >> $LOG
"$@" | tee -a $LOG

View file

@ -1,65 +0,0 @@
#!/bin/js
// Function to handle getattr command
function getattr(path,opts){
let size = 1
if (path === '/' || opts.obj ){
return "16877 2 0 0 4096 8\n"
} else {
return `33188 1 0 0 ${size} 1\n`
}
}
function getPath(str){
const scene = document.querySelector('a-scene').object3D
const path = str.split("/")
const name = path.pop()
const parent = path.pop()
let obj = name == ""
? scene
: scene.getObjectByName( name ) ||
scene.getObjectById( parseInt(name.substr(1)) )
console.dir({parent,name,obj})
return {obj,propname:name}
}
// Main function to handle commands
function main(args) {
console.log( 'fs/THREE '+args.join(' ') )
let children = ''
let props = ['uuid','position','rotation']
switch (args[0]) {
case 'readdir':{
const {obj} = getPath( args[1] )
if( obj && obj.children ){
children = obj.children.map( (n) => n.name || n.id )
.join("\n")
}
return `${children}\n${props.join('\n')}\n`
break;
}
case 'getattr':{
const opts = getPath( args[1] )
return getattr(args[1],{...opts, args});
break;
}
case 'read':{
const {obj,propname} = getPath( args[1] )
return obj[propname];
break;
}
default:
return ''
}
}
// Run the main function
return main(args.slice(1));

View file

@ -1,36 +0,0 @@
#!/bin/sh
LOG=~/.fuse.log
file1="hello world"
echo "$0 $*" >> $LOG
{
case "$1" in
readdir)
echo "file1"
;;
getattr)
# format: mode nlink uid gid size block
case "$2" in
/)
echo "16877 2 0 0 4096 8" && exit 0 # dir (mode 0755)
;;
/file1)
echo "33188 1 0 0 ${#file1} 1" && exit 0 # file (mode 0644, size 6)
;;
esac
exit 1
;;
read)
case "$2" in
/file1)
echo "$file1"
;;
esac
;;
*)
exit 1
;;
esac
} | tee -a $LOG

View file

@ -1,27 +0,0 @@
#!/usr/bin/awk -f
BEGIN {
LOG = ENVIRON["HOME"] "/.fuse.log"
file1 = "hello world"
log_command()
if (ARGC < 2) exit 1
cmd = ARGV[1]; path = (ARGC > 2 ? ARGV[2] : "")
if (cmd == "readdir") print "file1"
else if (cmd == "getattr") print_getattr(path)
else if (cmd == "read" && path == "/file1") print file1
else exit 1
}
function log_command() {
for (i = 0; i < ARGC; i++) printf "%s ", ARGV[i] >> LOG
print "" >> LOG; close(LOG)
}
function print_getattr(p) {
if (p == "/") print "16877 2 0 0 4096 8"
else if (p == "/file1") print "33188 1 0 0 " length(file1) " 1"
else exit 1
}

View file

@ -1,39 +0,0 @@
#!/bin/js
// Set log file to the home directory
const file1 = "hello world";
// Function to handle getattr command
function getattr(path) {
if (path === '/') {
return "16877 2 0 0 4096 8"
} else if (path === '/file1') {
return `33188 1 0 0 ${file1.length} 1`
} else {
return ''
}
}
// Main function to handle commands
function main(args) {
console.log(args.join(' '));
switch (args[0]) {
case 'readdir':
return 'file1'
break;
case 'getattr':
return getattr(args[1]);
break;
case 'read':
if (args[1] === '/file1') {
return file1;
}
break;
default:
return ''
}
}
// Run the main function
return main(args.slice(1));

View file

@ -1,23 +0,0 @@
#!/usr/bin/env lua
LOG_PATH, file1 = os.getenv("HOME") .. "/.fuse.log", "hello world"
local function log_command(args)
io.open(LOG_PATH, "a"):write(table.concat(args, " ") .. "\n"):close()
end
local function getattr(path)
if path == "/" then print("16877 2 0 0 4096 8")
elseif path == "/file1" then print(string.format("33188 1 0 0 %d 1", #file1))
else os.exit(1) end
end
local function main(args)
log_command(args)
if args[1] == "readdir" then print("file1")
elseif args[1] == "getattr" then getattr(args[2])
elseif args[1] == "read" and args[2] == "/file1" then print(file1)
else os.exit(1) end
end
main({...})

View file

@ -1,17 +0,0 @@
#!/usr/bin/env micropython
LOG_PATH = os.path.join(os.getenv("HOME", "/tmp"), ".fuse.log")
file1 = "hello world"
def log(msg): open(LOG_PATH, "a").write(msg + "\n")
def getattr(path): return {"16877 2 0 0 4096 8" if path == "/" else f"33188 1 0 0 {len(file1)} 1"} if path in ["/", "/file1"] else None
def readdir(): print("file1")
def read(path): print(file1) if path == "/file1" else sys.exit(1)
log(" ".join(sys.argv))
if len(sys.argv) < 2: sys.exit(1)
cmd, path = sys.argv[1], sys.argv[2] if len(sys.argv) > 2 else None
if cmd == "readdir": readdir()
elif cmd == "getattr": print(getattr(path)) if getattr(path) else sys.exit(1)
elif cmd == "read": read(path)
else: sys.exit(1)

View file

@ -1 +0,0 @@
/home/leon/.ctags.js

View file

@ -1,2 +0,0 @@
echo "[$(pwd)] polyglot hooks https://xrsh.isvery.ninja/#Unixy%20event%20hooks"

View file

@ -1,24 +0,0 @@
#!/bin/sh
source /etc/profile.sh # expose xrsh cmds like require etc
if [[ "$1" =~ "pos=|t=" ]]; then
# we are dealing with XR or Media Fragments (ignore for now)
echo "[.] detected Media/XR Fragment in URI"
fi
if [[ "$1" =~ "access_token=" ]]; then
# remotestorage redirect oAuth
exit 0
fi
if [[ "$1" =~ "zip$" ]]; then
echo "[.] detected XRSH zip package in URL"
echo "[.] fetching $1"
require "$1"
fi
# otherwise execute
echo "" # clear line
$* # simply execute
echo "$*" >> /tmp/frag.log

View file

@ -1 +0,0 @@
../../bin/helloworld.awk

View file

@ -1 +0,0 @@
../../bin/helloworld.js

View file

@ -1 +0,0 @@
../../bin/helloworld.lua

View file

@ -1 +0,0 @@
../../bin/helloworld.py

View file

@ -1,14 +0,0 @@
#!/bin/sh
# usage: hook clipboard foo.mp3 [audio/mpeg]
# this forwards the hook to mimetype or filetype
source /etc/profile.sh
file="$1"
ext="${file##*.}"
mimetype="$2"
if test -n "$mimetype"; then
hook mimetype/"$mimetype" "$file"
else
hook filetype $ext "$file"
fi

View file

@ -1 +0,0 @@
../../../bin/a-text

View file

@ -1,13 +0,0 @@
#!/usr/bin/awk -f
BEGIN{
href=ARGV[1]
if( match(href,/\.glb[#?]?/) ){
print( "<a-entity xrf='" href "'></a-entity>" ) > "/root/index.html"
}else{
system("js 'window.open(\"" href "\")'" )
}
}

View file

@ -1 +0,0 @@
../../filetype/mp3

View file

@ -1,5 +0,0 @@
#!/bin/sh
# usage: import-to-aframe <textfile>
# *FIXME* need consent
cat "$1" >> /root/index.html

View file

@ -1,9 +0,0 @@
#!/bin/sh
source /etc/profile.sh
file="$1"
# naive javascript detector
grep '<a-' "$file" &> /dev/null && {
cat "$file" | grep -vE '(<script|iframe)' &> "$file".aframe
hook mimetype/text/aframe "$file".aframe
}

View file

@ -1,8 +0,0 @@
#!/bin/sh
source /etc/profile.sh
file="$1"
# naive html detector
grep -E '(<\/a>|<\/div>)' "$file" &> /dev/null && {
hook mimetype/text/html "$file"
}

View file

@ -1,8 +0,0 @@
#!/bin/sh
source /etc/profile.sh
file="$1"
# naive javascript detector
grep -E '[a-zA-Z]\(' "$file" &> /dev/null && {
hook mimetype/text/javascript "$file"
}

View file

@ -1,11 +0,0 @@
#!/bin/sh
# this detects when a zip-url is copy/pasted to the clipboard
# and forwards it the zip mimetype hook
test -f /etc/profile.sh && source /etc/profile.sh
file="$1"
grep -E '^http.*\.zip$' "$file" &>/dev/null && {
file="$(cat $file)"
zip="${file/.*\/\//}"
wget "$zip" && hook clipboard $(pwd)/$(basename "$zip") application/zip
}

View file

@ -1,5 +0,0 @@
#!/bin/sh
# warning: to activate below make this file executable at own risk
cat $1 | grep -vE "(<script|<iframe)" >> /root/index.html

View file

@ -1,5 +0,0 @@
#!/bin/sh
# warning: to activate below make this file executable at own risk
js "$(cat $1)"

View file

@ -1 +0,0 @@
../../filetype/txt

View file

@ -1 +0,0 @@
../../filetype/mp4

View file

@ -1,11 +0,0 @@
#!/bin/sh
# launcher init
/root/bin/launcher init &
# intialize global funcs
/root/index.js &> /dev/null
# initialize scene
/root/index.html &> /dev/null

View file

@ -2,12 +2,4 @@
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0.05 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<!--
<a-box position="0 1.4 -0.5" scale="0.2 0.2 0.2" color="#FF00AA" grabbable></a-box>
-->
<!-- for [lowerlevel] THREE.js code see ~/index.js -->
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>

Some files were not shown because too many files have changed in this diff Show more