summaryrefslogtreecommitdiffstats
path: root/libsh
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2016-02-14 21:46:40 (EST)
committer P. J. McDermott <pj@pehjota.net>2016-02-14 21:46:40 (EST)
commit5da1775daf87fe38d46dcdeef6ed64c6fac0bd29 (patch)
tree0389b995add0684e7c8f0099d810dc3a7fb7ce0c /libsh
downloadeggshell-5da1775daf87fe38d46dcdeef6ed64c6fac0bd29.zip
eggshell-5da1775daf87fe38d46dcdeef6ed64c6fac0bd29.tar.gz
eggshell-5da1775daf87fe38d46dcdeef6ed64c6fac0bd29.tar.bz2
Initial commit
Diffstat (limited to 'libsh')
-rw-r--r--libsh/alias.sh56
-rw-r--r--libsh/errno.sh53
-rw-r--r--libsh/rand.sh46
-rw-r--r--libsh/stdio.sh123
4 files changed, 278 insertions, 0 deletions
diff --git a/libsh/alias.sh b/libsh/alias.sh
new file mode 100644
index 0000000..2945910
--- /dev/null
+++ b/libsh/alias.sh
@@ -0,0 +1,56 @@
+# Copyright (C) 2016 Patrick "P. J." McDermott
+#
+# This file is part of libsh.
+#
+# libsh is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# libsh is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with libsh. If not, see
+# <http://www.gnu.org/licenses/>.
+
+static check_args()
+{
+ local params="${1}"
+ shift 1
+ local p=
+
+ IFS=' '
+ for p in ${params}; do
+ unset IFS
+ if ! [ ${#} -gt 0 ]; then
+ return 1
+ fi
+ case "${p}" in
+ 'string')
+ ;;
+ 'int')
+ case "${1}" in *[!0-9]*) return 1;; esac
+ ;;
+ esac
+ shift 1
+ done
+ unset IFS
+
+ if ! [ ${#} -eq 0 ]; then
+ return 1
+ fi
+
+ return 0
+}
+
+__alias()
+{
+ local fn="${1}"
+ local alias="${2}"
+ local params="${*}"
+
+ eval "${alias}() { ${check_args} \"\${params}\" \"\${@}\" && ${fn}; }"
+}
diff --git a/libsh/errno.sh b/libsh/errno.sh
new file mode 100644
index 0000000..a0f9648
--- /dev/null
+++ b/libsh/errno.sh
@@ -0,0 +1,53 @@
+# Copyright (C) 2016 Patrick "P. J." McDermott
+#
+# This file is part of libsh.
+#
+# libsh is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# libsh is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with libsh. If not, see
+# <http://www.gnu.org/licenses/>.
+
+static errlist='
+ EINVAL 1
+ EUNK 2
+ EMFILE 3
+ EACCES 4
+ ENOENT 5
+ EISDIR 6
+ EBADF 7
+ '
+
+static strerror()
+{
+ local errnum=${1}
+
+ eval "msgget \"\${__errsym_${errnum}}\""
+}
+
+static init_error_syms()
+{
+ IFS=' '
+ while read errsym errno; do
+ eval "${errsym}=${errno}"
+ eval "__errsym_${errno}=${errsym}"
+ done <<-EOF
+ ${errlist}
+ EOF
+ unset IFS
+}
+__init ${init_error_syms}
+
+static errno_alias()
+{
+ __alias ${strerror} strerror int
+}
+__init ${errno_alias}
diff --git a/libsh/rand.sh b/libsh/rand.sh
new file mode 100644
index 0000000..07347d3
--- /dev/null
+++ b/libsh/rand.sh
@@ -0,0 +1,46 @@
+# Copyright (C) 2014, 2016 Patrick "P. J." McDermott
+#
+# This file is part of libsh.
+#
+# libsh is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# libsh is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with libsh. If not, see
+# <http://www.gnu.org/licenses/>.
+
+RAND_MAX=2147483647 # 2^31 - 1
+
+static x=1
+
+rand_x=1
+
+static srand()
+{
+ local s="${1}"
+
+ x=${s}
+ rand_x=${s}
+}
+
+static rand()
+{
+ # Multiplier, increment, and modulus values are those used in glibc.
+ x=$((1103515245 * ${x} + 12345))
+ x=$((${x} % (${RAND_MAX} + 1)))
+ rand_x=${x}
+}
+
+static rand_alias()
+{
+ __alias ${srand} srand int
+ __alias ${rand} rand
+}
+__init ${rand_alias}
diff --git a/libsh/stdio.sh b/libsh/stdio.sh
new file mode 100644
index 0000000..7d44d12
--- /dev/null
+++ b/libsh/stdio.sh
@@ -0,0 +1,123 @@
+# Copyright (C) 2013, 2016 Patrick "P. J." McDermott
+#
+# This file is part of libsh.
+#
+# libsh is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# libsh is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with libsh. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Shells and the file descriptors they reserve for the user:
+# * Debian Almquist Shell
+# - The shell doesn't understand any file descriptor greater than 9.
+# - File descriptors starting at 10 are used for I/O redirection.
+# * BusyBox ash
+# - File descriptors starting at 10 are used for job control and I/O
+# redirection.
+# * GNU Bash:
+# - GNU Readline uses file descriptor 255 in interactive shells.
+# - File descriptors starting at 10 are used for I/O redirection.
+# * MirOS Korn Shell
+# - File descriptors starting at either 10 or 24 are used for the shell's
+# tty_fd and shl_dbg_fd.
+# * Solaris ksh
+# - The shell doesn't understand any file descriptor greater than 9.
+static fd_min=3
+static fd_max=9
+
+static fd_3_set=false
+static fd_4_set=false
+static fd_5_set=false
+static fd_6_set=false
+static fd_7_set=false
+static fd_8_set=false
+static fd_9_set=false
+
+fd=0
+
+static fopen()
+{
+ local path="${1}"
+ local mode="${2}"
+ local mode_r=
+ local mode_w=
+ local i=
+ local f=
+
+ case "${mode}" in
+ 'r') mode_r=true mode_w=false mode='<' ;;
+ 'r+') mode_r=true mode_w=true mode='<>';;
+ 'w') mode_r=false mode_w=true mode='>' ;;
+ 'a') mode_r=false mode_w=true mode='>>';;
+ *) return ${EINVAL};;
+ esac
+
+ # Find first available file descriptor.
+ i=${fd_min}
+ while [ ${i} -le ${fd_max} ]; do
+ if ! $(eval "printf '%s' \${fd_${i}_set}"); then
+ f=${i}
+ break
+ fi
+ i=$(($i + 1))
+ done
+ if [ "x${f}" = 'x' ]; then
+ return ${EMFILE}
+ fi
+
+ # Check file mode and existence.
+ if ${mode_r} && ! [ -r "${path}" ]; then
+ return ${EACCES}
+ fi
+ if ${mode_w} && ! [ -w "${path}" ]; then
+ return ${EACCES}
+ fi
+ if ! [ -e "${path}" ]; then
+ return ${ENOENT}
+ fi
+ if [ -d "${path}" ]; then
+ return ${EISDIR}
+ fi
+
+ if ! eval "exec ${f}${mode}'${path}'" 2>/dev/null; then
+ return ${EUNK}
+ fi
+
+ eval "fd_${f}_set=true"
+ fd="${f}"
+ return 0
+}
+
+static fclose()
+{
+ local f=${1}
+
+ # Make sure the file descriptor is valid and open.
+ if [ ${f} -lt ${fd_min} ] || [ ${f} -gt ${fd_max} ]; then
+ return ${EINVAL}
+ fi
+ if $(eval "printf '%s' \${fd_${i}_set}"); then
+ return ${EBADF}
+ fi
+
+ eval "exec ${f}>&-"
+ unset "fd_${f}"
+
+ return 0
+}
+
+static stdio_alias()
+{
+ __alias ${fopen} fopen string string
+ __alias ${fclose} fclose int
+}
+__init ${stdio_alias}