From 5da1775daf87fe38d46dcdeef6ed64c6fac0bd29 Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Sun, 14 Feb 2016 21:46:40 -0500 Subject: Initial commit --- (limited to 'libsh') 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 +# . + +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 +# . + +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 +# . + +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 +# . + +# 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} -- cgit v0.9.1