From 19cd1eda1020e1feb0fed0d04e072cd0a8ab7d00 Mon Sep 17 00:00:00 2001 From: CyberLeo Date: Fri, 13 Apr 2012 09:34:47 -0500 Subject: [PATCH] j: add ipc to allow spawning editors and browsers outside chroot from files inside chroot --- ipcc | 34 +++++++++++++++++++++++++++++++ ipcd | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ j | 38 +++++++++++++++++++++++++++++++++-- 3 files changed, 135 insertions(+), 2 deletions(-) create mode 100755 ipcc create mode 100755 ipcd diff --git a/ipcc b/ipcc new file mode 100755 index 0000000..7104ccf --- /dev/null +++ b/ipcc @@ -0,0 +1,34 @@ +#!/bin/sh -e + +jipc="/tmp/jipc" + +[ -p "${jipc}" ] || { echo "ipcc: ${jipc} not found; ipcd not running?" >&2; exit 1; } + +pebkac() { + echo "Usage: ipcc " + echo "Or: ee " + echo "Or: ff " + echo "" + echo "Command can be one of 'editor' or 'browser'; argument should be a single file." + echo "Simplified wrappers 'ee' for editor and 'ff' for browser can also be used." + exit 1 +} + +case "$(basename "${0}")" in +ipcc) cmd="${1}"; shift ;; +ee) cmd="editor" ;; +ff) cmd="browser" ;; +*) pebkac ;; +esac +arg="${1}" + +case "${cmd}" in +editor|edit|ee) + echo "${arg}" | grep -q '^/' || arg="$(pwd)/${arg}" + echo "editor ${arg}" > "${jipc}" + ;; +browser|browse|ff) + echo "${arg}" | grep -vq "://" && echo "${arg}" | grep -vq '^/' && arg="$(pwd)/${arg}" + echo "browser ${arg}" > "${jipc}" ;; +*) pebkac ;; +esac diff --git a/ipcd b/ipcd new file mode 100755 index 0000000..05e03e5 --- /dev/null +++ b/ipcd @@ -0,0 +1,65 @@ +#!/bin/sh -e + +# These should be executable, and take a single parameter +editor="/home/cyberleo/.fhs/bin/ee" +browser="/home/cyberleo/.fhs/bin/ff" + +jroot="${1}/root" +jipc="${jroot}/tmp/jipc" +mkdir -p "$(dirname "${jipc}")" + +[ ! -p "${jipc}" ] || { echo "jipc already running? ${jipc} exists" >&2; exit 1; } +mkfifo -m 666 "${jipc}" +trap "rm -f '${jipc}'" EXIT HUP INT TERM KILL +echo "Listening on ${jipc} ..." >&2 + +resolve_path() { + path="${1}" + echo "${path}" | grep -q '^/' && echo "${jroot}${path}" || zenity --error --text="Only absolute paths are allowed in chroot protocol:\n${path}" +} + +do_editor() { + arg="${1}" + arg="$(resolve_path "${arg}")" + ( "${editor}" "${arg}" || zenity --error --text="Error launching editor:\n${editor} ${arg}" ) & +} + +do_browser() { + arg="${1}" + case "${arg}" in + file://*) + arg="${arg##file://}" + arg="$(resolve_path "${arg}")" + [ "${arg}" ] && arg="file://${arg}" + ;; + [a-z]*://*) + ;; + *) + arg="$(resolve_path "${arg}")" + [ "${arg}" ] && arg="file://${arg}" + ;; + esac + [ "${arg}" ] && ( "${browser}" "${arg}" || zenity --error --text="Error launching browser:\n${browser} ${arg}" ) & +} + +do_error() { + cmd="${1}" + arg="${2}" + zenity --error --text="Unrecognized verb in protocol:\n${cmd} ${arg}" +} + +while true +do + unset cmd arg + [ -p "${jipc}" ] || break + read cmd arg 2>&- < "${jipc}" + [ "${cmd}" ] || continue + cmd="$(echo "${cmd}" | tr '[A-Z]' '[a-z]')" + case "${cmd}" in + exit|die|kill) kill $$; exit 0 ;; + editor) do_editor "${arg}" ;; + browser) do_browser "${arg}" ;; + *) do_error "${cmd}" "${arg}" ;; + esac + sleep 0.25 +done diff --git a/j b/j index 067cbba..47c1c3d 100755 --- a/j +++ b/j @@ -2,8 +2,10 @@ # Copyright 2011 CyberLeo, All Rights Reserved # http://wiki.cyberleo.net/wiki/CyberLeo/COPYRIGHT +: ${ORIG_USER=$(id -un)} + # Need root beyond here -[ "$(id -u)" -eq 0 ] || exec sudo env "J_ARCH=${J_ARCH}" "J_BASE=${J_BASE}" "J_NAME=${J_NAME}" "J_USER=${J_USER:-${USER}}" "${0}" "${@}" +[ "$(id -u)" -eq 0 ] || exec sudo env "J_ARCH=${J_ARCH}" "J_BASE=${J_BASE}" "J_NAME=${J_NAME}" "J_USER=${J_USER:-${USER}}" "ORIG_USER=${ORIG_USER}" "DISPLAY=${DISPLAY}" "${0}" "${@}" meh() { printf " \033[1;32m*\033[0m %s%s\n" "${jname:+${jname}: }" "${*}"; } omg() { printf " \033[1;33m*\033[0m %s%s\n" "${jname:+${jname}: }" "${*}"; } @@ -68,7 +70,7 @@ j_init_debian() { cmd="debootstrap --arch=${arch} --include=curl,file,less,locales,sudo,build-essential,libreadline-dev,zlib1g-dev '${suite}' '${jdir}'" echo "Executing ${cmd}" eval "${cmd}" - + # Make sure locales are generated on first start mkdir -p "${jdir}/etc/rcJ.d" cat > "${jdir}/etc/rcJ.d/S00localegen" <<"EOF" @@ -147,6 +149,31 @@ j_params() { ) } +# Copy ipcc into the jail and add helpful symlinks, so it can communicate +# simple commands to the outside +j_ipc_setup() { + ipcc="$(dirname "${0}")/ipcc" + cp -f "${ipcc}" "${jroot}/bin" + ( cd "${jroot}/bin" + [ -e ee ] || ln -s ipcc ee + [ -e ff ] || ln -s ipcc ff + ) +} + +# Launch ipcd on jail +j_ipc_start() { + ipcd_pid="${jdir}/ipcd.pid" + su "${ORIG_USER}" "${jbase}/j/ipcd" "${jdir}" & + echo "${!}" > "${ipcd_pid}" +} + +# Stop ipcd on jail +j_ipc_stop() { + ipcd_pid="${jdir}/ipcd.pid" + [ -f "${ipcd_pid}" ] && pid="$(cat "${ipcd_pid}")" + [ "${pid}" ] && kill -TERM ${pid} +} + # Is this a chroot? j_is() { eval $(j_params "${1}") @@ -190,6 +217,10 @@ j_start() { mount -t devpts devpts "${jroot}/dev/pts" mount -t proc proc "${jroot}/proc" + # Copy in ipcc and launch ipcd + j_ipc_setup + j_ipc_start + # Start all services in /etc/rcJ.d j_root_eval "${jname}" '[ -d /etc/rcJ.d ] && ( ls -1 /etc/rcJ.d/* 2>&- | grep /S | sort | sed -e "s/$/ start/" | sh )' } @@ -228,6 +259,9 @@ j_stop() { # Stop all services in /etc/rcJ.d j_root_eval "${jname}" '[ -d /etc/rcJ.d ] && ( ls -1 /etc/rcJ.d/* 2>&- | grep /S | sort -r | sed -e "s/$/ stop/" | sh )' + # Terminate ipcd + j_ipc_stop + umount "${jroot}/proc" umount "${jroot}/dev/pts" } -- 2.42.0