From 88a7d6ce66995a1da21dbc29bad7061857f4d20f Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Thu, 4 Jul 2013 10:01:00 +0000 Subject: [PATCH] New frontend demo skript frontend/sh_on_named_pipes.sh --- frontend/sh_on_named_pipes.sh | 304 ++++++++++++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100755 frontend/sh_on_named_pipes.sh diff --git a/frontend/sh_on_named_pipes.sh b/frontend/sh_on_named_pipes.sh new file mode 100755 index 00000000..57755523 --- /dev/null +++ b/frontend/sh_on_named_pipes.sh @@ -0,0 +1,304 @@ +#!/bin/bash +# +# Demo of a shell frontend that communicates with a xorriso slave via +# two named pipes. +# +# This script creates two named pipes and starts xorriso with command +# -named_pipes_loop cleanup /tmp/xorriso_stdin_pipe_$$ xorriso_stdin_pipe_$$ - +# Its main loop prompts the user for commands, sends them to xorriso, +# receives the replies, and parses them by xorriso command +# -msg_op parse_silently. The resulting words are printed to stdout. +# +# xorriso removes the two pipes when it finishes execution of -named_pipes_loop +# regularly. (E.g. because of commands -end or -rollback_end or because of +# name loop control message "end_named_pipe_loop".) +# The vanishing of the pipe files tells this script that xorriso is gone. +# +# +# Copyright (C) 2013 +# Thomas Schmitt , libburnia-project.org +# Provided under BSD license: Use, modify, and distribute as you like. +# + +# What xorriso program to use +xorriso=xorriso +if test o"$1" = o"-xorriso" +then + xorriso="$2" +fi + +# Version of xorriso and minimum requirement by this script +export xorriso_version= +export xorriso_version_req=1.3.1 + +# Info about the xorriso slave process +export xorriso_is_running=0 +export xorriso_pid=0 +export xorriso_will_end=0 + +# Will be set to 1 before this script ends normally +export normal_end=0 + + +# ---------------- An interpreter for quoted xorriso replies ---------------- + +# xorriso commands like -lsl wrap filenames into quotation marks in order +# to unambigously represent any character byte except the 0-byte. +# This piece of code parses input strings into words by letting xorriso +# command -msg_op "parse_silently" do the hard work. +# The input strings should be composed by concatenating input lines with +# newline characters inbetween. Begin by submitting a single line (without +# newline at its end) and retry with an appended further line, if +# xorriso_parse +# returns 1. See below xorriso_cmd_and_handle_result() for an example. + + +# The parsed reply words. +# Valid are reply_array[0] to reply_array[reply_count-1)] +export reply_array +export reply_count + + +# Interpret reply of -msg_op parse +xorriso_recv_parse_reply() { + reply_count=0 + unset reply_array + export reply_array + ret=-1 + read ret + if test "$ret" -lt 0 -o -z "$ret" + then + echo "Unexpected text as first reply line of -msg_op parse" >&2 + xorriso_is_running=0 + return 2 + fi + test "$ret" = 0 && return "1" + read num_strings + string_count=0 + while true + do + test "$string_count" -ge "$num_strings" && break + read num_lines + line_count=0 + acc= + while true + do + test "$line_count" -ge "$num_lines" && break + read line + test "$line_count" -gt 0 && acc="$acc"$'\n' + acc="$acc""$line" + line_count=$(($line_count + 1)) + done + reply_array["$string_count"]="$acc" + string_count=$(($string_count + 1)) + done + reply_count="$num_strings" + return 0 +} + + +# Parse a quoted multi-line string into words +xorriso_parse() { + # $1 : The string which shall be parsed + # $2 : The number of concatenated input lines (= number of newlines + 1) + # return: 0= array is valid , 1= line incomplete , 2= other error + + test "$xorriso_is_running" = 0 && return 1 + xorriso_send_cmd "msg_op parse_silently "'"'"'' '' 0 0 $2"'"'$'\n'"$1" || \ + return 2 + xorriso_recv_parse_reply <"$result_pipe" || xorriso_is_running=0 + ret=$? + test "$xorriso_is_running" = 0 && ret=2 + return "$ret" +} + + +# ------------- End of interpreter for quoted xorriso replies -------------- + + +# Send one or more command lines to xorriso +xorriso_send_cmd() { + # $1 : the lines to send + + # >>> is it possible to have a timeout on echo ? + + if test -p "$cmd_pipe" + then + echo -E "$1" >"$cmd_pipe" + else + xorriso_is_running=0 + return 1 + fi +} + + +# Make filenames safe for transport by wrapping them in quotes and +# escaping quotes in their text +xorriso_esc() { + echo -n "'" + echo -n "$1" | sed -e "s/'/'"'"'"'"'"'"'/g" + echo -n "'" +} + + +# A handler function for xorriso_cmd_and_handle_result +xorriso_reply_to_stdout() { + echo "${reply_array[*]}" +} + + +# Let a handler inspect the result lines of a xorriso command line +xorriso_cmd_and_handle_result() { + # $1: handler command word and possibly argument words + # $2: command line for xorriso + + if test "$xorriso_is_running" = 0 + then + return 1 + fi + + handler="$1" + xorriso_send_cmd "$2" || return 1 + res=$(cat "$result_pipe") + ret=$? + if test "$xorriso_will_end" = 1 -o "$xorriso_is_running" = 0 -o "$ret" -ne 0 + then + test -n "$res" && echo -n "$res" + xorriso_is_running=0 + test "$ret" = 0 || return 1 + return 0 + fi + test -z "$res" && return 0 + echo "$res" | \ + while read line + do + line_count=1 + while true + do + xorriso_parse "$line" "$line_count" + ret=$? + test "$ret" = 0 && break + if test "$ret" = 2 + then + return 1 + fi + read addon + line="$line"$'\n'"$addon" + line_count=$(expr "$line_count" + 1) + done + # One can now make use of reply_array[0...(reply_count-1)] + $handler + done + return 0 +} + + +# Execute -version and let xorriso_version_handler interpret reply +xorriso_check_version() { + lookfor='^xorriso version : ' + xorriso_version=$("$xorriso" -version 2>/dev/null | grep "$lookfor" | \ + sed -e "s/${lookfor}//") + ret=$? + if test "$ret" -ne 0 -o "$xorriso_version" = "" + then + echo "SORRY: Program run '${xorriso}' -version did not yield a result." >&2 + echo >&2 + exit 2 + fi + smallest=$((echo "$xorriso_version_req" ; echo "$xorriso_version" ) | \ + sort | head -1) + test "$smallest" = "$xorriso_version_req" && return 0 + echo "SORRY: xorriso version too old: ${xorriso_version} . Need at least xorriso-${xorriso_version_req} ." >&2 + echo >&2 + exit 2 +} + + +# To be executed on exit +xorriso_cleanup() { + + send_end_cmd=0 + if test -p "$cmd_pipe" -a "$xorriso_is_running" = 1 + then + if test "$normal_end" = 0 + then + echo "Checking whether xorriso is still running ..." >&2 + set -x + # Give xorriso time to abort + sleep 1 + if ps | grep '^'"$xorriso_pid" >/dev/null + then + + # >>> try to further confirm xorriso identity + + send_end_cmd=1 + fi + else + send_end_cmd=1 + fi + fi + test "$normal_end" = 0 && set -x + if test "$send_end_cmd" = 1 + then + echo "Sending xorriso an -end command ..." >&2 + xorriso_send_cmd "end" && \ + test -p "$result_pipe" && cat "$result_pipe" >/dev/null + fi + test -p "$cmd_pipe" && rm "$cmd_pipe" + test -p "$result_pipe" && rm "$result_pipe" +} + + +# ---------------------------------- main --------------------------------- + +# Choose pipe names +export cmd_pipe=/tmp/xorriso_stdin_pipe_$$ +export result_pipe=/tmp/xorriso_stdout_pipe_$$ + +# Check the program whether it is modern enough +xorriso_check_version "$xorriso" + +# Prepare for then end of this script +trap xorriso_cleanup EXIT + +# Create the pipes and start xorriso +mknod "$cmd_pipe" p +mknod "$result_pipe" p +"$xorriso" -abort_on NEVER -for_backup \ + -named_pipe_loop cleanup:buffered "$cmd_pipe" "$result_pipe" "-" & +xorriso_pid=$! +xorriso_is_running=1 + +# Get a sign of life from xorriso before issueing the loop prompt +xorriso_cmd_and_handle_result xorriso_reply_to_stdout \ + "print_info 'xorriso process ${xorriso_pid} started by $0'" +echo >&2 + + +# Now get commands from the user, send them to xorriso and display them +# via the simple handler xorriso_reply_to_stdout() +while test "$xorriso_is_running" = 1 +do + if test -p "$cmd_pipe" + then + echo -n "xorriso> " >&2 + else + echo "$0 : Lost contact to xorriso process $xorriso_pid" >&2 + xorriso_is_running=0 + break + fi + read line + if echo "$line" | grep '^-*end$' >/dev/null + then + break + fi + if echo "$line" | grep '^-*rollback_end$' >/dev/null + then + xorriso_will_end=1 + fi + xorriso_cmd_and_handle_result xorriso_reply_to_stdout "$line" +done + +# Prevent set -x in the exit handler +normal_end=1 +