#!/bin/sh
# Syd: rock-solid application kernel
# data/syd.sh: Defines 'esyd' command, the multi functional syd helper.
#
# esyd is written in portable shell.
# It should work fine with POSIX sh, Bash and Zsh.
# If you spot a problem running this with either of them,
# please report a bug at: https://todo.sr.ht/~alip/syd
#
# Copyright (c) 2023, 2024, 2025, 2026 Ali Polatel <alip@chesswob.org>
# SPDX-License-Identifier: GPL-3.0

esyd() {
    cmd="${1}"

    shift
    case "${cmd}" in
    api)
        printf '%d' 3
        ;;
    check)
        test -c /dev/syd
        ;;
    panic|reset|stat)
        [ -c /dev/syd/"${cmd}" ]
        ;;
    load)
        if [ ${#} -ne 1 ]; then
            echo >&2 "esyd: ${cmd} takes exactly one extra argument"
            return 1
        fi
        [ -c "/dev/syd/load/${1}" ]
        ;;
    lock)
        [ -c '/dev/syd/lock:on' ]
        ;;
    unlock)
        [ -c '/dev/syd/lock:off' ]
        ;;
    exec_lock)
        [ -c '/dev/syd/lock:exec' ]
        ;;
    drop_lock)
        [ -c '/dev/syd/lock:drop' ]
        ;;
    read_lock)
        [ -c '/dev/syd/lock:read' ]
        ;;
    info)
        if [ -c /dev/syd ]; then
            # Note we cannot spawn a subshell here,
            # while reading from `/dev/syd` otherwise
            # this will break with lock:exec.
            while IFS= read -r dat || [ -n "${dat}" ]; do
                syd="${syd}${dat}"
            done </dev/syd

            if command -v jq >/dev/null 2>&1; then
                printf '%s' "${syd}" | jq "${@}"
            else
                printf '%s' "${syd}"
            fi
        else
            return 1
        fi
        ;;
    mem_max)
        if [ ${#} -ne 1 ]; then
            echo >&2 "esyd: ${cmd} takes exactly one extra argument"
            return 1
        fi
        [ -c "/dev/syd/mem/max:${1}" ]
        ;;
    vm_max)
        if [ ${#} -ne 1 ]; then
            echo >&2 "esyd: ${cmd} takes exactly one extra argument"
            return 1
        fi
        [ -c "/dev/syd/mem/vm_max:${1}" ]
        ;;
    kill_mem)
        [ -c '/dev/syd/mem/kill:1' ]
        ;;
    nokill_mem)
        [ -c '/dev/syd/mem/kill:0' ]
        ;;
    filter_mem)
        [ -c '/dev/syd/filter/mem:1' ]
        ;;
    unfilter_mem)
        [ -c '/dev/syd/filter/mem:0' ]
        ;;
    pid_max)
        if [ ${#} -ne 1 ]; then
            echo >&2 "esyd: ${cmd} takes exactly one extra argument"
            return 1
        fi
        [ -c "/dev/syd/pid/max:${1}" ]
        ;;
    kill_pid)
        [ -c '/dev/syd/pid/kill:1' ]
        ;;
    nokill_pid)
        [ -c '/dev/syd/pid/kill:0' ]
        ;;
    filter_pid)
        [ -c '/dev/syd/filter/pid:1' ]
        ;;
    unfilter_pid)
        [ -c '/dev/syd/filter/pid:0' ]
        ;;
    exec)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        [ -c "$(syd-exec "${@}")" ]
        ;;
    force)
        if [ ${#} -ne 4 ]; then
            echo >&2 "esyd: ${cmd} takes exactly four arguments"
            return 1
        fi
        _esyd_path 'force' '+' "${1}:${2}:${3}:${4}"
        ;;
    enabled|enabled_path)
        test -c '/dev/syd/sandbox/all?'
        ;;
    enable|enable_path)
        test -c '/dev/syd/sandbox/all:on'
        ;;
    disable|disable_path)
        test -c '/dev/syd/sandbox/all:off'
        ;;
    enabled_mem)
        [ -c '/dev/syd/sandbox/mem?' ]
        ;;
    disable_mem)
        [ -c '/dev/syd/sandbox/mem:off' ]
        ;;
    enabled_pid)
        [ -c '/dev/syd/sandbox/pid?' ]
        ;;
    enable_pid)
        [ -c '/dev/syd/sandbox/pid:on' ]
        ;;
    disable_pid)
        [ -c '/dev/syd/sandbox/pid:off' ]
        ;;
    enabled_fs)
        [ -c '/dev/syd/sandbox/fs?' ]
        ;;
    enable_fs)
        [ -c '/dev/syd/sandbox/fs:on' ]
        ;;
    disable_fs)
        [ -c '/dev/syd/sandbox/fs:off' ]
        ;;
    enabled_walk)
        [ -c '/dev/syd/sandbox/walk?' ]
        ;;
    enable_walk)
        [ -c '/dev/syd/sandbox/walk:on' ]
        ;;
    disable_walk)
        [ -c '/dev/syd/sandbox/walk:off' ]
        ;;
    enabled_stat)
        [ -c '/dev/syd/sandbox/stat?' ]
        ;;
    enable_stat)
        [ -c '/dev/syd/sandbox/stat:on' ]
        ;;
    disable_stat)
        [ -c '/dev/syd/sandbox/stat:off' ]
        ;;
    enabled_read)
        [ -c '/dev/syd/sandbox/read?' ]
        ;;
    enable_read)
        [ -c '/dev/syd/sandbox/read:on' ]
        ;;
    disable_read)
        [ -c '/dev/syd/sandbox/read:off' ]
        ;;
    enabled_write)
        [ -c '/dev/syd/sandbox/write?' ]
        ;;
    enable_write)
        [ -c '/dev/syd/sandbox/write:on' ]
        ;;
    disable_write)
        [ -c '/dev/syd/sandbox/write:off' ]
        ;;
    enabled_exec)
        [ -c '/dev/syd/sandbox/exec?' ]
        ;;
    enable_exec)
        [ -c '/dev/syd/sandbox/exec:on' ]
        ;;
    disable_exec)
        [ -c '/dev/syd/sandbox/exec:off' ]
        ;;
    enabled_ioctl)
        [ -c '/dev/syd/sandbox/ioctl?' ]
        ;;
    enable_ioctl)
        [ -c '/dev/syd/sandbox/ioctl:on' ]
        ;;
    disable_ioctl)
        [ -c '/dev/syd/sandbox/ioctl:off' ]
        ;;
    enabled_create)
        [ -c '/dev/syd/sandbox/create?' ]
        ;;
    enable_create)
        [ -c '/dev/syd/sandbox/create:on' ]
        ;;
    disable_create)
        [ -c '/dev/syd/sandbox/create:off' ]
        ;;
    enabled_delete)
        [ -c '/dev/syd/sandbox/delete?' ]
        ;;
    enable_delete)
        [ -c '/dev/syd/sandbox/delete:on' ]
        ;;
    disable_delete)
        [ -c '/dev/syd/sandbox/delete:off' ]
        ;;
    enabled_rename)
        [ -c '/dev/syd/sandbox/rename?' ]
        ;;
    enable_rename)
        [ -c '/dev/syd/sandbox/rename:on' ]
        ;;
    disable_rename)
        [ -c '/dev/syd/sandbox/rename:off' ]
        ;;
    enabled_symlink)
        [ -c '/dev/syd/sandbox/symlink?' ]
        ;;
    enable_symlink)
        [ -c '/dev/syd/sandbox/symlink:on' ]
        ;;
    disable_symlink)
        [ -c '/dev/syd/sandbox/symlink:off' ]
        ;;
    enabled_truncate)
        [ -c '/dev/syd/sandbox/truncate?' ]
        ;;
    enable_truncate)
        [ -c '/dev/syd/sandbox/truncate:on' ]
        ;;
    disable_truncate)
        [ -c '/dev/syd/sandbox/truncate:off' ]
        ;;
    enabled_chdir)
        [ -c '/dev/syd/sandbox/chdir?' ]
        ;;
    enable_chdir)
        [ -c '/dev/syd/sandbox/chdir:on' ]
        ;;
    disable_chdir)
        [ -c '/dev/syd/sandbox/chdir:off' ]
        ;;
    enabled_readdir)
        [ -c '/dev/syd/sandbox/readdir?' ]
        ;;
    enable_readdir)
        [ -c '/dev/syd/sandbox/readdir:on' ]
        ;;
    disable_readdir)
        [ -c '/dev/syd/sandbox/readdir:off' ]
        ;;
    enabled_mkdir)
        [ -c '/dev/syd/sandbox/mkdir?' ]
        ;;
    enable_mkdir)
        [ -c '/dev/syd/sandbox/mkdir:on' ]
        ;;
    disable_mkdir)
        [ -c '/dev/syd/sandbox/mkdir:off' ]
        ;;
    enabled_rmdir)
        [ -c '/dev/syd/sandbox/rmdir?' ]
        ;;
    enable_rmdir)
        [ -c '/dev/syd/sandbox/rmdir:on' ]
        ;;
    disable_rmdir)
        [ -c '/dev/syd/sandbox/rmdir:off' ]
        ;;
    enabled_chown)
        [ -c '/dev/syd/sandbox/chown?' ]
        ;;
    enable_chown)
        [ -c '/dev/syd/sandbox/chown:on' ]
        ;;
    disable_chown)
        [ -c '/dev/syd/sandbox/chown:off' ]
        ;;
    enabled_chgrp)
        [ -c '/dev/syd/sandbox/chgrp?' ]
        ;;
    enable_chgrp)
        [ -c '/dev/syd/sandbox/chgrp:on' ]
        ;;
    disable_chgrp)
        [ -c '/dev/syd/sandbox/chgrp:off' ]
        ;;
    enabled_chmod)
        [ -c '/dev/syd/sandbox/chmod?' ]
        ;;
    enable_chmod)
        [ -c '/dev/syd/sandbox/chmod:on' ]
        ;;
    disable_chmod)
        [ -c '/dev/syd/sandbox/chmod:off' ]
        ;;
    enabled_chattr)
        [ -c '/dev/syd/sandbox/chattr?' ]
        ;;
    enable_chattr)
        [ -c '/dev/syd/sandbox/chattr:on' ]
        ;;
    disable_chattr)
        [ -c '/dev/syd/sandbox/chattr:off' ]
        ;;
    enabled_chroot)
        [ -c '/dev/syd/sandbox/chroot?' ]
        ;;
    enable_chroot)
        [ -c '/dev/syd/sandbox/chroot:on' ]
        ;;
    disable_chroot)
        [ -c '/dev/syd/sandbox/chroot:off' ]
        ;;
    enabled_notify)
        [ -c '/dev/syd/sandbox/notify?' ]
        ;;
    enable_notify)
        [ -c '/dev/syd/sandbox/notify:on' ]
        ;;
    disable_notify)
        [ -c '/dev/syd/sandbox/notify:off' ]
        ;;
    enabled_utime)
        [ -c '/dev/syd/sandbox/utime?' ]
        ;;
    enable_utime)
        [ -c '/dev/syd/sandbox/utime:on' ]
        ;;
    disable_utime)
        [ -c '/dev/syd/sandbox/utime:off' ]
        ;;
    enabled_mkbdev)
        [ -c '/dev/syd/sandbox/mkbdev?' ]
        ;;
    enable_mkbdev)
        [ -c '/dev/syd/sandbox/mkbdev:on' ]
        ;;
    disable_mkbdev)
        [ -c '/dev/syd/sandbox/mkbdev:off' ]
        ;;
    enabled_mkcdev)
        [ -c '/dev/syd/sandbox/mkcdev?' ]
        ;;
    enable_mkcdev)
        [ -c '/dev/syd/sandbox/mkcdev:on' ]
        ;;
    disable_mkcdev)
        [ -c '/dev/syd/sandbox/mkcdev:off' ]
        ;;
    enabled_mkfifo)
        [ -c '/dev/syd/sandbox/mkfifo?' ]
        ;;
    enable_mkfifo)
        [ -c '/dev/syd/sandbox/mkfifo:on' ]
        ;;
    disable_mkfifo)
        [ -c '/dev/syd/sandbox/mkfifo:off' ]
        ;;
    enabled_mktemp)
        [ -c '/dev/syd/sandbox/mktemp?' ]
        ;;
    enable_mktemp)
        [ -c '/dev/syd/sandbox/mktemp:on' ]
        ;;
    disable_mktemp)
        [ -c '/dev/syd/sandbox/mktemp:off' ]
        ;;
    enabled_net)
        [ -c '/dev/syd/sandbox/net?' ]
        ;;
    enable_net)
        [ -c '/dev/syd/sandbox/net:on' ]
        ;;
    disable_net)
        [ -c '/dev/syd/sandbox/net:off' ]
        ;;
    enabled_force)
        [ -c '/dev/syd/sandbox/force?' ]
        ;;
    disable_force)
        [ -c '/dev/syd/sandbox/force:off' ]
        ;;
    allow|allow_path)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        # allow is shorthand for all glob capabilities.
        _esyd_path "allow/all" '+' "${@}"
        ;;
    disallow|disallow_path)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        # disallow is shorthand for all glob capabilities.
        _esyd_path "allow/all" "${op}" "${@}"
        ;;
    deny|deny_path)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        # deny is shorthand for all glob capabilities.
        _esyd_path "deny/all" '+' "${@}"
        ;;
    nodeny|nodeny_path)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        # nodeny is shorthand for all glob capabilities.
        _esyd_path "deny/all" "${op}" "${@}"
        ;;
    allow_fs)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/fs' '+' "${@}"
        ;;
    disallow_fs)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/fs' "${op}" "${@}"
        ;;
    deny_fs)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/fs' '+' "${@}"
        ;;
    nodeny_fs)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/fs' "${op}" "${@}"
        ;;
    allow_walk)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/walk' '+' "${@}"
        ;;
    disallow_walk)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/walk' "${op}" "${@}"
        ;;
    deny_walk)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/walk' '+' "${@}"
        ;;
    nodeny_walk)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/walk' "${op}" "${@}"
        ;;
    allow_stat)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/stat' '+' "${@}"
        ;;
    disallow_stat)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/stat' "${op}" "${@}"
        ;;
    deny_stat)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/stat' '+' "${@}"
        ;;
    nodeny_stat)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/stat' "${op}" "${@}"
        ;;
    allow_read)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/read' '+' "${@}"
        ;;
    disallow_read)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/read' "${op}" "${@}"
        ;;
    deny_read)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/read' '+' "${@}"
        ;;
    nodeny_read)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/read' "${op}" "${@}"
        ;;
    allow_write)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/write' '+' "${@}"
        ;;
    disallow_write)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/write' "${op}" "${@}"
        ;;
    deny_write)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/write' '+' "${@}"
        ;;
    nodeny_write)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/write' "${op}" "${@}"
        ;;
    allow_exec)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/exec' '+' "${@}"
        ;;
    disallow_exec)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/exec' "${op}" "${@}"
        ;;
    deny_exec)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/exec' '+' "${@}"
        ;;
    nodeny_exec)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/exec' "${op}" "${@}"
        ;;
    allow_ioctl)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/ioctl' '+' "${@}"
        ;;
    disallow_ioctl)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/ioctl' "${op}" "${@}"
        ;;
    deny_ioctl)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/ioctl' '+' "${@}"
        ;;
    nodeny_ioctl)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/ioctl' "${op}" "${@}"
        ;;
    allow_create)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/create' '+' "${@}"
        ;;
    disallow_create)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/create' "${op}" "${@}"
        ;;
    deny_create)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/create' '+' "${@}"
        ;;
    nodeny_create)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/create' "${op}" "${@}"
        ;;
    allow_delete)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/delete' '+' "${@}"
        ;;
    disallow_delete)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/delete' "${op}" "${@}"
        ;;
    deny_delete)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/delete' '+' "${@}"
        ;;
    nodeny_delete)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/delete' "${op}" "${@}"
        ;;
    allow_rename)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/rename' '+' "${@}"
        ;;
    disallow_rename)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/rename' "${op}" "${@}"
        ;;
    deny_rename)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/rename' '+' "${@}"
        ;;
    nodeny_rename)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/rename' "${op}" "${@}"
        ;;
    allow_symlink)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/symlink' '+' "${@}"
        ;;
    disallow_symlink)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/symlink' "${op}" "${@}"
        ;;
    deny_symlink)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/symlink' '+' "${@}"
        ;;
    nodeny_symlink)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/symlink' "${op}" "${@}"
        ;;
    allow_truncate)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/truncate' '+' "${@}"
        ;;
    disallow_truncate)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/truncate' "${op}" "${@}"
        ;;
    deny_truncate)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/truncate' '+' "${@}"
        ;;
    nodeny_truncate)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/truncate' "${op}" "${@}"
        ;;
    allow_chdir)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/chdir' '+' "${@}"
        ;;
    disallow_chdir)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/chdir' "${op}" "${@}"
        ;;
    deny_chdir)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/chdir' '+' "${@}"
        ;;
    nodeny_chdir)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/chdir' "${op}" "${@}"
        ;;
    allow_readdir)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/readdir' '+' "${@}"
        ;;
    disallow_readdir)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/readdir' "${op}" "${@}"
        ;;
    deny_readdir)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/readdir' '+' "${@}"
        ;;
    nodeny_readdir)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/readdir' "${op}" "${@}"
        ;;
    allow_mkdir)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/mkdir' '+' "${@}"
        ;;
    disallow_mkdir)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/mkdir' "${op}" "${@}"
        ;;
    deny_mkdir)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/mkdir' '+' "${@}"
        ;;
    nodeny_mkdir)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/mkdir' "${op}" "${@}"
        ;;
    allow_rmdir)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/rmdir' '+' "${@}"
        ;;
    disallow_rmdir)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/rmdir' "${op}" "${@}"
        ;;
    deny_rmdir)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/rmdir' '+' "${@}"
        ;;
    nodeny_rmdir)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/rmdir' "${op}" "${@}"
        ;;
    allow_chown)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/chown' '+' "${@}"
        ;;
    disallow_chown)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/chown' "${op}" "${@}"
        ;;
    deny_chown)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/chown' '+' "${@}"
        ;;
    nodeny_chown)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/chown' "${op}" "${@}"
        ;;
    allow_chgrp)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/chgrp' '+' "${@}"
        ;;
    disallow_chgrp)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/chgrp' "${op}" "${@}"
        ;;
    deny_chgrp)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/chgrp' '+' "${@}"
        ;;
    nodeny_chgrp)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/chgrp' "${op}" "${@}"
        ;;
    allow_chmod)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/chmod' '+' "${@}"
        ;;
    disallow_chmod)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/chmod' "${op}" "${@}"
        ;;
    deny_chmod)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/chmod' '+' "${@}"
        ;;
    nodeny_chmod)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/chmod' "${op}" "${@}"
        ;;
    allow_chattr)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/chattr' '+' "${@}"
        ;;
    disallow_chattr)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/chattr' "${op}" "${@}"
        ;;
    deny_chattr)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/chattr' '+' "${@}"
        ;;
    nodeny_chattr)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/chattr' "${op}" "${@}"
        ;;
    allow_chroot)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/chroot' '+' "${@}"
        ;;
    disallow_chroot)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/chroot' "${op}" "${@}"
        ;;
    deny_chroot)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/chroot' '+' "${@}"
        ;;
    nodeny_chroot)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/chroot' "${op}" "${@}"
        ;;
    allow_notify)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/notify' '+' "${@}"
        ;;
    disallow_notify)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/notify' "${op}" "${@}"
        ;;
    deny_notify)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/notify' '+' "${@}"
        ;;
    nodeny_notify)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/notify' "${op}" "${@}"
        ;;
    allow_utime)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/utime' '+' "${@}"
        ;;
    disallow_utime)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/utime' "${op}" "${@}"
        ;;
    deny_utime)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/utime' '+' "${@}"
        ;;
    nodeny_utime)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/utime' "${op}" "${@}"
        ;;
    allow_mkbdev)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/mkbdev' '+' "${@}"
        ;;
    disallow_mkbdev)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/mkbdev' "${op}" "${@}"
        ;;
    deny_mkbdev)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/mkbdev' '+' "${@}"
        ;;
    nodeny_mkbdev)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/mkbdev' "${op}" "${@}"
        ;;
    allow_mkcdev)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/mkcdev' '+' "${@}"
        ;;
    disallow_mkcdev)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/mkcdev' "${op}" "${@}"
        ;;
    deny_mkcdev)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/mkcdev' '+' "${@}"
        ;;
    nodeny_mkcdev)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/mkcdev' "${op}" "${@}"
        ;;
    allow_mkfifo)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/mkfifo' '+' "${@}"
        ;;
    disallow_mkfifo)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/mkfifo' "${op}" "${@}"
        ;;
    deny_mkfifo)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/mkfifo' '+' "${@}"
        ;;
    nodeny_mkfifo)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/mkfifo' "${op}" "${@}"
        ;;
    allow_mktemp)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/mktemp' '+' "${@}"
        ;;
    disallow_mktemp)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'allow/mktemp' "${op}" "${@}"
        ;;
    deny_mktemp)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/mktemp' '+' "${@}"
        ;;
    nodeny_mktemp)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'deny/mktemp' "${op}" "${@}"
        ;;
    allow_net)
        op='-'
        c='allow/net/bind'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        case "${1}" in
        '--connect')
            c='allow/net/connect'
            shift;;
        '--sendfd')
            c='allow/net/sendfd'
            shift;;
        esac
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_net "${c}" '+' "${@}"
        ;;
    disallow_net)
        op='-'
        c='allow/net/bind'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        case "${1}" in
        '--connect')
            c='allow/net/connect'
            shift;;
        '--sendfd')
            c='allow/net/sendfd'
            shift;;
        esac
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_net "${c}" "${op}" "${@}"
        ;;
    deny_net)
        op='-'
        c='deny/net/bind'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        case "${1}" in
        '--connect')
            c='allow/net/connect'
            shift;;
        '--sendfd')
            c='allow/net/sendfd'
            shift;;
        esac
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_net "${c}" '+' "${@}"
        ;;
    nodeny_net)
        op='-'
        c='deny/net/bind'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        case "${1}" in
        '--connect')
            c='allow/net/connect'
            shift;;
        '--sendfd')
            c='allow/net/sendfd'
            shift;;
        esac
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_net "${c}" "${op}" "${@}"
        ;;
    addfilter|addfilter_path)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        for capability in walk stat read write ioctl create delete rename symlink truncate chdir readdir mkdir rmdir chown chgrp chmod chattr chroot mkbdev mkcdev mkfifo mktemp; do
            _esyd_path "filter/${capability}" '+' "${@}" || return 1
        done
        ;;
    rmfilter|rmfilter_path)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        for capability in walk stat read write ioctl create delete rename symlink truncate chdir readdir mkdir rmdir chown chgrp chmod chattr chroot mkbdev mkcdev mkfifo mktemp; do
            _esyd_path "filter/${capability}" "${op}" "${@}" || return 1
        done
        ;;
    addfilter_fs)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/fs' '+' "${@}"
        ;;
    rmfilter_fs)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/fs' "${op}" "${@}"
        ;;
    addfilter_walk)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/walk' '+' "${@}"
        ;;
    rmfilter_walk)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/walk' "${op}" "${@}"
        ;;
    addfilter_stat)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/stat' '+' "${@}"
        ;;
    rmfilter_stat)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/stat' "${op}" "${@}"
        ;;
    addfilter_read)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/read' '+' "${@}"
        ;;
    rmfilter_read)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/read' "${op}" "${@}"
        ;;
    addfilter_write)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/write' '+' "${@}"
        ;;
    rmfilter_write)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/write' "${op}" "${@}"
        ;;
    addfilter_exec)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/exec' '+' "${@}"
        ;;
    rmfilter_exec)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/exec' "${op}" "${@}"
        ;;
    addfilter_ioctl)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/ioctl' '+' "${@}"
        ;;
    rmfilter_ioctl)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/ioctl' "${op}" "${@}"
        ;;
    addfilter_create)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/create' '+' "${@}"
        ;;
    rmfilter_create)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/create' "${op}" "${@}"
        ;;
    addfilter_delete)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/delete' '+' "${@}"
        ;;
    rmfilter_delete)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/delete' "${op}" "${@}"
        ;;
    addfilter_rename)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/rename' '+' "${@}"
        ;;
    rmfilter_rename)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/rename' "${op}" "${@}"
        ;;
    addfilter_symlink)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/symlink' '+' "${@}"
        ;;
    rmfilter_symlink)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/symlink' "${op}" "${@}"
        ;;
    addfilter_truncate)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/truncate' '+' "${@}"
        ;;
    rmfilter_truncate)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/truncate' "${op}" "${@}"
        ;;
    addfilter_chdir)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/chdir' '+' "${@}"
        ;;
    rmfilter_chdir)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/chdir' "${op}" "${@}"
        ;;
    addfilter_readdir)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/readdir' '+' "${@}"
        ;;
    rmfilter_readdir)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/readdir' "${op}" "${@}"
        ;;
    addfilter_mkdir)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/mkdir' '+' "${@}"
        ;;
    rmfilter_mkdir)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/mkdir' "${op}" "${@}"
        ;;
    addfilter_rmdir)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/rmdir' '+' "${@}"
        ;;
    rmfilter_rmdir)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/rmdir' "${op}" "${@}"
        ;;
    addfilter_chown)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/chown' '+' "${@}"
        ;;
    rmfilter_chown)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/chown' "${op}" "${@}"
        ;;
    addfilter_chgrp)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/chgrp' '+' "${@}"
        ;;
    rmfilter_chgrp)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/chgrp' "${op}" "${@}"
        ;;
    addfilter_chmod)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/chmod' '+' "${@}"
        ;;
    rmfilter_chmod)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/chmod' "${op}" "${@}"
        ;;
    addfilter_chattr)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/chattr' '+' "${@}"
        ;;
    rmfilter_chattr)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/chattr' "${op}" "${@}"
        ;;
    addfilter_chroot)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/chroot' '+' "${@}"
        ;;
    rmfilter_chroot)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/chroot' "${op}" "${@}"
        ;;
    addfilter_notify)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/notify' '+' "${@}"
        ;;
    rmfilter_notify)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/notify' "${op}" "${@}"
        ;;
    addfilter_utime)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/utime' '+' "${@}"
        ;;
    rmfilter_utime)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/utime' "${op}" "${@}"
        ;;
    addfilter_mkbdev)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/mkbdev' '+' "${@}"
        ;;
    rmfilter_mkbdev)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/mkbdev' "${op}" "${@}"
        ;;
    addfilter_mkcdev)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/mkcdev' '+' "${@}"
        ;;
    rmfilter_mkcdev)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/mkcdev' "${op}" "${@}"
        ;;
    addfilter_mkfifo)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/mkfifo' '+' "${@}"
        ;;
    rmfilter_mkfifo)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/mkfifo' "${op}" "${@}"
        ;;
    addfilter_mktemp)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/mktemp' '+' "${@}"
        ;;
    rmfilter_mktemp)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if  [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_path 'filter/mktemp' "${op}" "${@}"
        ;;
    addfilter_net)
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_net 'filter/net' '+' "${@}"
        ;;
    rmfilter_net)
        op='-'
        [ x"${1}" = 'x--all' ] && op='^' && shift
        if [ ${#} -lt 1 ]; then
            echo >&2 "esyd: ${cmd} takes at least one extra argument"
            return 1
        fi
        _esyd_net 'filter/net' "${op}" "${@}"
        ;;
    help|'')
        if [ -t 1 ]; then
            esyd help | ${PAGER:-less}
            return $?
        fi

        cat <<EOF
esyd -- multi functional syd helper
Copyright (c) 2023, 2024 Ali Polatel <alip@chesswob.org>
SPDX-License-Identifier: GPL-3.0

# Subcommands
api
    Print syd API version number
check
    Return true if running under Syd
lock
    Lock Syd, esyd commands will no longer work
exec_lock
    Lock Syd for all processes but the syd exec child
drop_lock
    Lock Syd in drop-only mode, allowing only privilege-dropping sandbox commands
read_lock
    Lock Syd in read-only-mode, allowing only read-only access to sandbox state
unlock
    Unlock Syd, make it available to all processes rather than just the Syd exec child
info jq-args...
    Print Syd sandbox state as JSON on standard output
    If "jq" is in PATH, pass the arguments and pipe the output to jq
load fd
    This command causes Syd to read configuration from the given file descriptor
panic
    This command causes Syd to exit immediately with code 127
reset
    This command causes Syd to reset sandboxing to the default state
    Allowlists, denylists and filters are going to be cleared
stat
    Print Syd sandbox state on standard error
exec cmd args..
    Execute a command outside the sandbox without sandboxing
kill glob
    Kill any attempt to execute a path matching the given glob pattern
force path alg hash action
    Force pre-execution verification of the given path using the given algorithm and checksum
    Action must be exactly one of exit, kill, abort, stop, panic, deny, filter or warn.
enabled, enabled_path
    Return true if path sandboxing is enabled
enable, enable_path
    Enable path sandboxing
disable, disable_path
    Disable path sandboxing
enabled_pid
    Return true if PID sandboxing is enabled
enable_pid
    Enable PID sandboxing
disable_pid
    Disable PID sandboxing
enabled_fs
    Return true if Filesystem sandboxing is enabled
enable_fs
    Enable Filesystem sandboxing
disable_fs
    Disable Filesystem sandboxing
enabled_walk
    Return true if walk sandboxing is enabled
enable_walk
    Enable walk sandboxing
disable_walk
    Disable walk sandboxing
enabled_stat
    Return true if stat sandboxing is enabled
enable_stat
    Enable stat sandboxing
disable_stat
    Disable stat sandboxing
enabled_read
    Return true if read sandboxing is enabled
enable_read
    Enable read sandboxing
disable_read
    Disable read sandboxing
enabled_write
    Return true if write sandboxing is enabled
enable_write
    Enable write sandboxing
disable_write
    Disable write sandboxing
enabled_exec
    Return true if exec sandboxing is enabled
enable_exec
    Enable exec sandboxing
disable_exec
    Disable exec sandboxing
enabled_ioctl
    Return true if ioctl sandboxing is enabled
enable_ioctl
    Enable ioctl sandboxing
disable_ioctl
    Disable ioctl sandboxing
enabled_create
    Return true if create sandboxing is enabled
enable_create
    Enable create sandboxing
disable_create
    Disable create sandboxing
enabled_delete
    Return true if delete sandboxing is enabled
enable_delete
    Enable delete sandboxing
disable_delete
    Disable delete sandboxing
enabled_rename
    Return true if rename sandboxing is enabled
enable_rename
    Enable rename sandboxing
disable_rename
    Disable rename sandboxing
enabled_symlink
    Return true if symlink sandboxing is enabled
enable_symlink
    Enable symlink sandboxing
disable_symlink
    Disable symlink sandboxing
enabled_truncate
    Return true if truncate sandboxing is enabled
enable_truncate
    Enable truncate sandboxing
disable_truncate
    Disable truncate sandboxing
enabled_chdir
    Return true if chdir sandboxing is enabled
enable_chdir
    Enable chdir sandboxing
disable_chdir
    Disable chdir sandboxing
enabled_readdir
    Return true if readdir sandboxing is enabled
enable_readdir
    Enable readdir sandboxing
disable_readdir
    Disable readdir sandboxing
enabled_mkdir
    Return true if mkdir sandboxing is enabled
enable_mkdir
    Enable mkdir sandboxing
disable_mkdir
    Disable mkdir sandboxing
enabled_rmdir
    Return true if rmdir sandboxing is enabled
enable_rmdir
    Enable rmdir sandboxing
disable_rmdir
    Disable rmdir sandboxing
enabled_chown
    Return true if chown sandboxing is enabled
enable_chown
    Enable chown sandboxing
disable_chown
    Disable chown sandboxing
enabled_chgrp
    Return true if chgrp sandboxing is enabled
enable_chgrp
    Enable chgrp sandboxing
disable_chgrp
    Disable chgrp sandboxing
enabled_chmod
    Return true if chmod sandboxing is enabled
enable_chmod
    Enable chmod sandboxing
disable_chmod
    Disable chmod sandboxing
enabled_chattr
    Return true if chattr sandboxing is enabled
enable_chattr
    Enable chattr sandboxing
disable_chattr
    Disable chattr sandboxing
enabled_chroot
    Return true if chroot sandboxing is enabled
enable_chroot
    Enable chroot sandboxing
disable_chroot
    Disable chroot sandboxing
enabled_notify
    Return true if notify sandboxing is enabled
enable_notify
    Enable notify sandboxing
disable_notify
    Disable notify sandboxing
enabled_utime
    Return true if utime sandboxing is enabled
enable_utime
    Enable utime sandboxing
disable_utime
    Disable utime sandboxing
enabled_mkbdev
    Return true if mkbdev sandboxing is enabled
enable_mkbdev
    Enable mkbdev sandboxing
disable_mkbdev
    Disable mkbdev sandboxing
enabled_mkcdev
    Return true if mkcdev sandboxing is enabled
enable_mkcdev
    Enable mkcdev sandboxing
disable_mkcdev
    Disable mkcdev sandboxing
enabled_mkfifo
    Return true if mkfifo sandboxing is enabled
enable_mkfifo
    Enable mkfifo sandboxing
disable_mkfifo
    Disable mkfifo sandboxing
enabled_mktemp
    Return true if mktemp sandboxing is enabled
enable_mktemp
    Enable mktemp sandboxing
disable_mktemp
    Disable mktemp sandboxing
enabled_net
    Return true if network sandboxing is enabled
enable_net
    Enable network sandboxing
disable_net
    Disable network sandboxing
enabled_force
    Return true if force sandboxing is enabled
disable_force
    Disable force sandboxing
allow, allow_path glob
    Allow the given glob pattern for path sandboxing
disallow, disallow_path [--all] glob
    Removes the given glob pattern from the allowlist for path sandboxing
deny, deny_path glob
    Deny the given glob pattern for path sandboxing
nodeny, nodeny_path [--all] glob
    Removes the given glob pattern from the denylist for path sandboxing
allow_fs fstype
    Allow the given filesystem type for Filesystem sandboxing
disallow_fs [--all] fstype
    Removes the given filesystem type from the allowlist for Filesystem sandboxing
deny_fs fstype
    Deny the given filesystem type for Filesystem sandboxing
nodeny_fs [--all] fstype
    Removes the given filesystem type from the denylist for Filesystem sandboxing
allow_walk glob
    Allow the given glob pattern for walk sandboxing
disallow_walk [--all] glob
    Removes the given glob pattern from the allowlist for walk sandboxing
deny_walk glob
    Deny the given glob pattern for walk sandboxing
nodeny_walk [--all] glob
    Removes the given glob pattern from the denylist for walk sandboxing
allow_stat glob
    Allow the given glob pattern for stat sandboxing
disallow_stat [--all] glob
    Removes the given glob pattern from the allowlist for stat sandboxing
deny_stat glob
    Deny the given glob pattern for stat sandboxing
nodeny_stat [--all] glob
    Removes the given glob pattern from the denylist for stat sandboxing
allow_read glob
    Allow the given glob pattern for read sandboxing
disallow_read [--all] glob
    Removes the given glob pattern from the allowlist for read sandboxing
deny_read glob
    Deny the given glob pattern for read sandboxing
nodeny_read [--all] glob
    Removes the given glob pattern from the denylist for read sandboxing
allow_write glob
    Allow the given glob pattern for write sandboxing
disallow_write [--all] glob
    Removes the given glob pattern from the allowlist for write sandboxing
deny_write glob
    Deny the given glob pattern for write sandboxing
nodeny_write [--all] glob
    Removes the given glob pattern from the denylist for write sandboxing
allow_exec glob
    Allow the given glob pattern for exec sandboxing
disallow_exec [--all] glob
    Removes the given glob pattern from the allowlist for exec sandboxing
deny_exec glob
    Deny the given glob pattern for exec sandboxing
nodeny_exec [--all] glob
    Removes the given glob pattern from the denylist for exec sandboxing
allow_ioctl glob
    Allow the given glob pattern for ioctl sandboxing
disallow_ioctl [--all] glob
    Removes the given glob pattern from the allowlist for ioctl sandboxing
deny_ioctl glob
    Deny the given glob pattern for ioctl sandboxing
nodeny_ioctl [--all] glob
    Removes the given glob pattern from the denylist for ioctl sandboxing
allow_create glob
    Allow the given glob pattern for create sandboxing
disallow_create [--all] glob
    Removes the given glob pattern from the allowlist for create sandboxing
deny_create glob
    Deny the given glob pattern for create sandboxing
nodeny_create [--all] glob
    Removes the given glob pattern from the denylist for create sandboxing
allow_delete glob
    Allow the given glob pattern for delete sandboxing
disallow_delete [--all] glob
    Removes the given glob pattern from the allowlist for delete sandboxing
deny_delete glob
    Deny the given glob pattern for delete sandboxing
nodeny_delete [--all] glob
    Removes the given glob pattern from the denylist for delete sandboxing
allow_rename glob
    Allow the given glob pattern for rename sandboxing
disallow_rename [--all] glob
    Removes the given glob pattern from the allowlist for rename sandboxing
deny_rename glob
    Deny the given glob pattern for rename sandboxing
nodeny_rename [--all] glob
    Removes the given glob pattern from the denylist for rename sandboxing
allow_symlink glob
    Allow the given glob pattern for symlink sandboxing
disallow_symlink [--all] glob
    Removes the given glob pattern from the allowlist for symlink sandboxing
deny_symlink glob
    Deny the given glob pattern for symlink sandboxing
nodeny_symlink [--all] glob
    Removes the given glob pattern from the denylist for symlink sandboxing
allow_truncate glob
    Allow the given glob pattern for truncate sandboxing
disallow_truncate [--all] glob
    Removes the given glob pattern from the allowlist for truncate sandboxing
deny_truncate glob
    Deny the given glob pattern for truncate sandboxing
nodeny_truncate [--all] glob
    Removes the given glob pattern from the denylist for truncate sandboxing
allow_chdir glob
    Allow the given glob pattern for chdir sandboxing
disallow_chdir [--all] glob
    Removes the given glob pattern from the allowlist for chdir sandboxing
deny_chdir glob
    Deny the given glob pattern for chdir sandboxing
nodeny_chdir [--all] glob
    Removes the given glob pattern from the denylist for chdir sandboxing
allow_readdir glob
    Allow the given glob pattern for readdir sandboxing
disallow_readdir [--all] glob
    Removes the given glob pattern from the allowlist for readdir sandboxing
deny_readdir glob
    Deny the given glob pattern for readdir sandboxing
nodeny_readdir [--all] glob
    Removes the given glob pattern from the denylist for readdir sandboxing
allow_mkdir glob
    Allow the given glob pattern for mkdir sandboxing
disallow_mkdir [--all] glob
    Removes the given glob pattern from the allowlist for mkdir sandboxing
deny_mkdir glob
    Deny the given glob pattern for mkdir sandboxing
nodeny_mkdir [--all] glob
    Removes the given glob pattern from the denylist for mkdir sandboxing
allow_rmdir glob
    Allow the given glob pattern for rmdir sandboxing
disallow_rmdir [--all] glob
    Removes the given glob pattern from the allowlist for rmdir sandboxing
deny_rmdir glob
    Deny the given glob pattern for rmdir sandboxing
nodeny_rmdir [--all] glob
    Removes the given glob pattern from the denylist for rmdir sandboxing
allow_chown glob
    Allow the given glob pattern for chown sandboxing
disallow_chown [--all] glob
    Removes the given glob pattern from the allowlist for chown sandboxing
deny_chown glob
    Deny the given glob pattern for chown sandboxing
nodeny_chown [--all] glob
    Removes the given glob pattern from the denylist for chown sandboxing
allow_chgrp glob
    Allow the given glob pattern for chgrp sandboxing
disallow_chgrp [--all] glob
    Removes the given glob pattern from the allowlist for chgrp sandboxing
deny_chgrp glob
    Deny the given glob pattern for chgrp sandboxing
nodeny_chgrp [--all] glob
    Removes the given glob pattern from the denylist for chgrp sandboxing
allow_chmod glob
    Allow the given glob pattern for chmod sandboxing
disallow_chmod [--all] glob
    Removes the given glob pattern from the allowlist for chmod sandboxing
deny_chmod glob
    Deny the given glob pattern for chmod sandboxing
nodeny_chmod [--all] glob
    Removes the given glob pattern from the denylist for chmod sandboxing
allow_chattr glob
    Allow the given glob pattern for chattr sandboxing
disallow_chattr [--all] glob
    Removes the given glob pattern from the allowlist for chattr sandboxing
deny_chattr glob
    Deny the given glob pattern for chattr sandboxing
nodeny_chattr [--all] glob
    Removes the given glob pattern from the denylist for chattr sandboxing
allow_chroot glob
    Allow the given glob pattern for chroot sandboxing
disallow_chroot [--all] glob
    Removes the given glob pattern from the allowlist for chroot sandboxing
deny_chroot glob
    Deny the given glob pattern for chroot sandboxing
nodeny_chroot [--all] glob
    Removes the given glob pattern from the denylist for chroot sandboxing
allow_notify glob
    Allow the given glob pattern for notify sandboxing
disallow_notify [--all] glob
    Removes the given glob pattern from the allowlist for notify sandboxing
deny_notify glob
    Deny the given glob pattern for notify sandboxing
nodeny_notify [--all] glob
    Removes the given glob pattern from the denylist for notify sandboxing
allow_utime glob
    Allow the given glob pattern for utime sandboxing
disallow_utime [--all] glob
    Removes the given glob pattern from the allowlist for utime sandboxing
deny_utime glob
    Deny the given glob pattern for utime sandboxing
nodeny_utime [--all] glob
    Removes the given glob pattern from the denylist for utime sandboxing
allow_mkbdev glob
    Allow the given glob pattern for mkbdev sandboxing
disallow_mkbdev [--all] glob
    Removes the given glob pattern from the allowlist for mkbdev sandboxing
deny_mkbdev glob
    Deny the given glob pattern for mkbdev sandboxing
nodeny_mkbdev [--all] glob
    Removes the given glob pattern from the denylist for mkbdev sandboxing
allow_mkcdev glob
    Allow the given glob pattern for mkcdev sandboxing
disallow_mkcdev [--all] glob
    Removes the given glob pattern from the allowlist for mkcdev sandboxing
deny_mkcdev glob
    Deny the given glob pattern for mkcdev sandboxing
nodeny_mkcdev [--all] glob
    Removes the given glob pattern from the denylist for mkcdev sandboxing
allow_mkfifo glob
    Allow the given glob pattern for mkfifo sandboxing
disallow_mkfifo [--all] glob
    Removes the given glob pattern from the allowlist for mkfifo sandboxing
deny_mkfifo glob
    Deny the given glob pattern for mkfifo sandboxing
nodeny_mkfifo [--all] glob
    Removes the given glob pattern from the denylist for mkfifo sandboxing
allow_mktemp glob
    Allow the given glob pattern for mktemp sandboxing
disallow_mktemp [--all] glob
    Removes the given glob pattern from the allowlist for mktemp sandboxing
deny_mktemp glob
    Deny the given glob pattern for mktemp sandboxing
nodeny_mktemp [--all] glob
    Removes the given glob pattern from the denylist for mktemp sandboxing
allow_net [--connect|--sendfd] glob|cidr!port[-port]
    Allow the given network address for network bind or connect sandboxing
disallow_net [--all] [--connect|--sendfd] glob|cidr!port[-port]
    Removes the given network address (Ipv4,6), or the glob pattern (UNIX domain sockets)
    from the allowlist for network bind or connect sandboxing
deny_net [--connect|--sendfd] glob|cidr!port[-port]
    Deny the given network address (Ipv4,6) or the glob pattern (UNIX domain sockets)
    for network bind or connect sandboxing
nodeny_net [--all] [--connect|--sendfd] glob|cidr!port[-port]
    Removes the given network address (Ipv4,6) or the glob pattern (UNIX domain sockets)
    from the denylist for network bind or connect sandboxing
addfilter, addfilter_path glob
    Adds the given glob pattern to the list of access violation filters for path sandboxing
rmfilter, rmfilter_path [--all] glob
    Removes the given glob pattern from the list of access violation filters for path sandboxing
addfilter_fs fstype
    Adds the given filesystem type to the list of access violation filters for Filesystem sandboxing
rmfilter_fs [--all] fstype
    Removes the given filesystem type from the list of access violation filters for Filesystem sandboxing
addfilter_walk glob
    Adds the given glob pattern to the list of access violation filters for walk sandboxing
rmfilter_walk [--all] glob
    Removes the given glob pattern from the list of access violation filters for walk sandboxing
addfilter_stat glob
    Adds the given glob pattern to the list of access violation filters for stat sandboxing
rmfilter_stat [--all] glob
    Removes the given glob pattern from the list of access violation filters for stat sandboxing
addfilter_read glob
    Adds the given glob pattern to the list of access violation filters for read sandboxing
rmfilter_read [--all] glob
    Removes the given glob pattern from the list of access violation filters for read sandboxing
addfilter_write glob
    Adds the given glob pattern to the list of access violation filters for write sandboxing
rmfilter_write [--all] glob
    Removes the given glob pattern from the list of access violation filters for write sandboxing
addfilter_exec glob
    Adds the given glob pattern to the list of access violation filters for exec sandboxing
rmfilter_exec [--all] glob
    Removes the given glob pattern from the list of access violation filters for exec sandboxing
addfilter_ioctl glob
    Adds the given glob pattern to the list of access violation filters for ioctl sandboxing
rmfilter_ioctl [--all] glob
    Removes the given glob pattern from the list of access violation filters for ioctl sandboxing
addfilter_create glob
    Adds the given glob pattern to the list of access violation filters for create sandboxing
rmfilter_create [--all] glob
    Removes the given glob pattern from the list of access violation filters for create sandboxing
addfilter_delete glob
    Adds the given glob pattern to the list of access violation filters for delete sandboxing
rmfilter_delete [--all] glob
    Removes the given glob pattern from the list of access violation filters for delete sandboxing
addfilter_rename glob
    Adds the given glob pattern to the list of access violation filters for rename sandboxing
rmfilter_rename [--all] glob
    Removes the given glob pattern from the list of access violation filters for rename sandboxing
addfilter_symlink glob
    Adds the given glob pattern to the list of access violation filters for symlink sandboxing
rmfilter_symlink [--all] glob
    Removes the given glob pattern from the list of access violation filters for symlink sandboxing
addfilter_truncate glob
    Adds the given glob pattern to the list of access violation filters for truncate sandboxing
rmfilter_truncate [--all] glob
    Removes the given glob pattern from the list of access violation filters for truncate sandboxing
addfilter_chdir glob
    Adds the given glob pattern to the list of access violation filters for chdir sandboxing
rmfilter_chdir [--all] glob
    Removes the given glob pattern from the list of access violation filters for chdir sandboxing
addfilter_readdir glob
    Adds the given glob pattern to the list of access violation filters for readdir sandboxing
rmfilter_readdir [--all] glob
    Removes the given glob pattern from the list of access violation filters for readdir sandboxing
addfilter_mkdir glob
    Adds the given glob pattern to the list of access violation filters for mkdir sandboxing
rmfilter_mkdir [--all] glob
    Removes the given glob pattern from the list of access violation filters for mkdir sandboxing
addfilter_rmdir glob
    Adds the given glob pattern to the list of access violation filters for rmdir sandboxing
rmfilter_rmdir [--all] glob
    Removes the given glob pattern from the list of access violation filters for rmdir sandboxing
addfilter_chown glob
    Adds the given glob pattern to the list of access violation filters for chown sandboxing
rmfilter_chown [--all] glob
    Removes the given glob pattern from the list of access violation filters for chown sandboxing
addfilter_chgrp glob
    Adds the given glob pattern to the list of access violation filters for chgrp sandboxing
rmfilter_chgrp [--all] glob
    Removes the given glob pattern from the list of access violation filters for chgrp sandboxing
addfilter_chmod glob
    Adds the given glob pattern to the list of access violation filters for chmod sandboxing
rmfilter_chmod [--all] glob
    Removes the given glob pattern from the list of access violation filters for chmod sandboxing
addfilter_chattr glob
    Adds the given glob pattern to the list of access violation filters for chattr sandboxing
rmfilter_chattr [--all] glob
    Removes the given glob pattern from the list of access violation filters for chattr sandboxing
addfilter_chroot glob
    Adds the given glob pattern to the list of access violation filters for chroot sandboxing
rmfilter_chroot [--all] glob
    Removes the given glob pattern from the list of access violation filters for chroot sandboxing
addfilter_notify glob
    Adds the given glob pattern to the list of access violation filters for notify sandboxing
rmfilter_notify [--all] glob
    Removes the given glob pattern from the list of access violation filters for notify sandboxing
addfilter_utime glob
    Adds the given glob pattern to the list of access violation filters for utime sandboxing
rmfilter_utime [--all] glob
    Removes the given glob pattern from the list of access violation filters for utime sandboxing
addfilter_mkbdev glob
    Adds the given glob pattern to the list of access violation filters for mkbdev sandboxing
rmfilter_mkbdev [--all] glob
    Removes the given glob pattern from the list of access violation filters for mkbdev sandboxing
addfilter_mkcdev glob
    Adds the given glob pattern to the list of access violation filters for mkcdev sandboxing
rmfilter_mkcdev [--all] glob
    Removes the given glob pattern from the list of access violation filters for mkcdev sandboxing
addfilter_mkfifo glob
    Adds the given glob pattern to the list of access violation filters for mkfifo sandboxing
rmfilter_mkfifo [--all] glob
    Removes the given glob pattern from the list of access violation filters for mkfifo sandboxing
addfilter_mktemp glob
    Adds the given glob pattern to the list of access violation filters for mktemp sandboxing
rmfilter_mktemp [--all] glob
    Removes the given glob pattern from the list of access violation filters for mktemp sandboxing
addfilter_net glob|cidr!port[-port]
    Adds the network address (Ipv4,6) or the glob pattern (UNIX domain sockets)
    to the list of access violation filters for network sandboxing
rmfilter_net [--all] glob|cidr!port[-port]
    Removes the network address (Ipv4,6) or the glob pattern (UNIX domain sockets)
    from the list of access violation filters for network sandboxing
mem_max
    Set Syd maximum per-process memory usage limit for memory sandboxing
    parse-size crate is used to parse the value so formatted strings are OK
vm_max
    Set Syd maximum per-process virtual memory usage limit for memory sandboxing
    parse-size crate is used to parse the value so formatted strings are OK
kill_mem
    Send SIGKILL to process on Memory access violation
nokill_mem
    Do not send SIGKILL to process on Memory access violation
    Deny system call with ENOMEM
filter_mem
    Do not report access violations for memory sandboxing
unfilter_mem
    Report access violations for memory sandboxing
pid_max
    Set Syd maximum process id limit for PID sandboxing
kill_pid
    Send SIGKILL to process on PID access violation
nokill_pid
    Do not send SIGKILL to process on PID access violation
    Deny system call with EACCES
filter_pid
    Do not report access violations for PID sandboxing
unfilter_pid
    Report access violations for PID sandboxing
EOF
        ;;
    *)
        echo >&2 "esyd: subcommand '${cmd}' unrecognised!"
        echo >&2 "Use 'esyd help' for a list of supported subcommands."
        return 1
        ;;
    esac
}

_esyd_path()
{
    cmd="${1}"
    op="${2}"

    case "${op}" in
    '+'|'-')
        ;;
    *)
        echo >&2 "esyd_path: invalid operation character '${op}'"
        return 1
        ;;
    esac

    shift 2

    ret=0
    for path in "${@}"; do
        case "${path}" in
        /*)
            [ -c /dev/syd/"${cmd}${op}${path}" ] || ret=$?
            ;;
        *)
            echo >&2 "esyd_path: expects absolute path, got: ${path}"
            return 1
            ;;
        esac
    done
    return $ret
}

_esyd_net()
{
    cmd="${1}"
    op="${2}"

    case "${op}" in
    '+'|'-')
        ;;
    *)
        echo >&2 "esyd_net: invalid operation character '${op}'"
        return 1
        ;;
    esac

    shift 2

    ret=0
    while [ ${#} -gt 0 ] ; do
        # syd does input validation so we don't do any here.
        [ -c "/dev/syd/${cmd}${op}${1}" ] || ret=$?
        shift
    done
    return $ret
}
