diff options
Diffstat (limited to 'examples/scripts/dd-ex.sh')
-rw-r--r-- | examples/scripts/dd-ex.sh | 476 |
1 files changed, 0 insertions, 476 deletions
diff --git a/examples/scripts/dd-ex.sh b/examples/scripts/dd-ex.sh deleted file mode 100644 index fafc83f2..00000000 --- a/examples/scripts/dd-ex.sh +++ /dev/null @@ -1,476 +0,0 @@ -#!/bin/sh - -# this is a line editor using only /bin/sh, /bin/dd and /bin/rm - -# /bin/rm is not really required, but it is nice to clean up temporary files - -PATH= -dd=/bin/dd -rm=/bin/rm - -# temporary files we might need -tmp=/tmp/silly.$$ -ed=/tmp/ed.$$ -trap "$rm -f $tmp $tmp.1 $tmp.2 $tmp.3 $tmp.4 $tmp.5 $tmp.6 $ed.a $ed.b $ed.c; exit" 0 1 2 3 - -# from now on, no more rm - the above trap is enough -unset rm - -# we do interesting things with IFS, but better save it... -saveIFS="$IFS" - -# in case "echo" is not a shell builtin... - -Echo () { -case "$1" in - -n) shift - $dd of=$tmp 2>/dev/null <<EOF -$@ -EOF - IFS="+" - set `$dd if=$tmp bs=1 of=/dev/null skip=1 2>&1` - IFS="$saveIFS" - $dd if=$tmp bs=1 count=$1 2>/dev/null - ;; - *) $dd 2>/dev/null <<EOF -$@ -EOF - ;; -esac -} - -# this is used to generate garbage files - -true () { - return 0 -} - -false () { - return 1 -} - -zero () { - ( trap 'go=false' 13 - go=true - while $go - do - $dd "if=$0" - case "$?" in - 0) ;; - *) go=false ;; - esac - done - ) 2>/dev/null -} - -# arithmetic using dd! - -# add variable n1 n2 n3... -# assigns n1+n2+n3+... to variable - -add () { - result="$1" - shift - $dd if=/dev/null of=$tmp bs=1 2>/dev/null - for n in "$@" - do - case "$n" in - 0) ;; - *) zero | $dd of=$tmp.1 bs=1 "count=$n" 2>/dev/null - ( $dd if=$tmp; $dd if=$tmp.1 ) 2>/dev/null | $dd of=$tmp.2 2>/dev/null - $dd if=$tmp.2 of=$tmp 2>/dev/null - ;; - esac - done - IFS="+" - set `$dd if=$tmp bs=1 of=/dev/null 2>&1` - IFS="$saveIFS" - eval $result='$1' -} - -# subtract variable n1 n2 -# subtracts n2 from n1, assigns result to variable - -subtract () { - result="$1" - zero | $dd of=$tmp bs=1 "count=$2" 2>/dev/null - IFS="+" - set `$dd if=$tmp bs=1 of=/dev/null "skip=$3" 2>&1` - IFS="$saveIFS" - case "$1" in - dd*) set 0 ;; - esac - eval $result='$1' -} - -# multiply variable n1 n2 -# variable = n1 * n2 - -multiply () { - result="$1" - zero | $dd "bs=$2" of=$tmp "count=$3" 2>/dev/null - IFS="+" - set `$dd if=$tmp bs=1 of=/dev/null 2>&1` - IFS="$saveIFS" - eval $result='$1' -} - -# divide variable n1 n2 -# variable = int( n1 / n2 ) - -divide () { - result="$1" - zero | $dd bs=1 of=$tmp "count=$2" 2>/dev/null - IFS="+" - set `$dd if=$tmp "bs=$3" of=/dev/null 2>&1` - IFS="$saveIFS" - eval $result='$1' -} - -# compare variable n1 n2 sets variable to lt if n1<n2, gt if n1>n2, eq if n1==n2 - -compare () { - res="$1" - n1="$2" - n2="$3" - subtract somename "$n1" "$n2" - case "$somename" in - 0) ;; - *) eval $res=gt; return; - esac - subtract somename "$n2" "$n1" - case "$somename" in - 0) ;; - *) eval $res=lt; return; - esac - eval $res=eq -} - -# lt n1 n2 returns true if n1 < n2 - -lt () { - n1="$1" - n2="$2" - subtract somename "$n2" "$n1" - case "$somename" in - 0) return 1 ;; - esac - return 0 -} - -# le n1 n2 returns true if n1 <= n2 - -le () { - n1="$1" - n2="$2" - subtract somename "$n1" "$n2" - case "$somename" in - 0) return 0 ;; - esac - return 1 -} - -# gt n1 n2 returns true if n1 > n2 - -gt () { - n1="$1" - n2="$2" - subtract somename "$n1" "$n2" - case "$somename" in - 0) return 1 ;; - esac - return 0 -} - -# ge n1 n2 returns true if n1 >= n2 - -ge () { - n1="$1" - n2="$2" - subtract somename "$n2" "$n1" - case "$somename" in - 0) return 0 ;; - esac - return 1 -} - -# useful functions for the line editor - -# open a file - copy it to the buffers - -open () { - file="$1" - set `$dd "if=$file" of=/dev/null 2>&1` - case "$1" in - dd*) return 1 - esac - # copy the first line to $ed.c - go=true - len=0 - while $go - do - case "`$dd "if=$file" bs=1 skip=$len count=1 2>/dev/null`" in - ?*) go=true ;; - *) go=false ;; - esac - add len 1 $len - done - # now $len is the length of the first line (including newline) - $dd "if=$file" bs=1 count=$len of=$ed.c 2>/dev/null - $dd "if=$file" bs=1 skip=$len of=$ed.b 2>/dev/null - $dd if=/dev/null of=$ed.a 2>/dev/null - lineno=1 -} - -# save a file - copy the buffers to the file - -save () { - # make a backup copy of the original - $dd "if=$1" "of=$1.bak" 2>/dev/null - # and save - ( $dd if=$ed.a; $dd if=$ed.c; $dd if=$ed.b ) > "$1" 2>/dev/null -} - -# replace n1 n2 bla replaces n2 chars of current line, starting n1-th - -replace () { - $dd if=$ed.c of=$tmp.1 bs=1 "count=$1" 2>/dev/null - ( $dd if=$ed.c "skip=$1" bs=1 | $dd of=$tmp.2 bs=1 "skip=$2" ) 2>/dev/null - shift - shift - ( $dd if=$tmp.1; Echo -n "$@"; $dd if=$tmp.2 ) > $tmp.3 2>/dev/null - $dd if=$tmp.3 of=$ed.c 2>/dev/null -} - -# rstring n s bla -# replace the n-th occurence of s with bla - -rstring () { - n="$1" - shift; - # first we have to find it - this is fun! - # we have $tmp.4 => text before string, $tmp.5 => text after - $dd if=/dev/null of=$tmp.4 2>/dev/null - $dd if=$ed.c of=$tmp.5 2>/dev/null - string="$1" - shift - $dd of=$tmp.6 2>/dev/null <<EOF -$@ -EOF - while : - do - case "`$dd if=$tmp.5 2>/dev/null`" in - $string*) - if lt $n 2 - then - # now we want to replace the string - Echo -n "$@" > $tmp.2 - Echo -n "$string" > $tmp.1 - IFS="+" - set `$dd bs=1 if=$tmp.1 of=/dev/null 2>&1` - IFS="$saveIFS" - slen=$1 - IFS="+" - ( $dd if=$tmp.4; $dd if=$tmp.2; $dd if=$tmp.5 bs=1 skip=$slen ) \ - 2>/dev/null > $tmp - $dd if=$tmp of=$ed.c 2>/dev/null - return 0 - else - subtract n $n 1 - ( $dd if=$tmp.4; $dd if=$tmp.5 bs=1 count=1 ) > $tmp 2>/dev/null - $dd if=$tmp of=$tmp.4 2>/dev/null - # and remove it from $tmp.5 - $dd if=$tmp.5 of=$tmp bs=1 skip=1 2>/dev/null - $dd if=$tmp of=$tmp.5 2>/dev/null - fi - ;; - ?*) # add one more byte... - ( $dd if=$tmp.4; $dd if=$tmp.5 bs=1 count=1 ) > $tmp 2>/dev/null - $dd if=$tmp of=$tmp.4 2>/dev/null - # and remove it from $tmp.5 - $dd if=$tmp.5 of=$tmp bs=1 skip=1 2>/dev/null - $dd if=$tmp of=$tmp.5 2>/dev/null - ;; - *) # not found - return 1 - ;; - esac - done -} - -# skip to next line -next () { - add l $lineno 1 - ( $dd if=$ed.a; $dd if=$ed.c ) 2>/dev/null > $tmp.3 - $dd if=$ed.b of=$tmp.4 2>/dev/null - open $tmp.4 - $dd if=$tmp.3 of=$ed.a 2>/dev/null - lineno=$l -} - -# delete current line -delete () { - l=$lineno - $dd if=$ed.a 2>/dev/null > $tmp.1 - $dd if=$ed.b of=$tmp.2 2>/dev/null - open $tmp.2 - $dd if=$tmp.1 of=$ed.a 2>/dev/null - lineno=$l -} - -# insert before current line (without changing current) -insert () { - ( $dd if=$ed.a; Echo "$@" ) 2>/dev/null > $tmp.1 - $dd if=$tmp.1 of=$ed.a 2>/dev/null - add lineno $lineno 1 -} - -# previous line -prev () { - case "$lineno" in - 1) ;; - *) subtract lineno $lineno 1 - # read last line of $ed.a - IFS='+' - set `$dd if=$ed.a of=/dev/null bs=1 2>&1` - IFS="$saveIFS" - size=$1 - # empty? - case "$size" in - 0) return ;; - esac - subtract size $size 1 - # skip final newline - case "$size" in - 0) ;; - *) subtract size1 $size 1 - case "`$dd if=$ed.a bs=1 skip=$size count=1 2>/dev/null`" in - ?*) ;; - *) size=$size1 ;; - esac - ;; - esac - go=true - while $go - do - case "$size" in - 0) go=false ;; - *) case "`$dd if=$ed.a bs=1 skip=$size count=1 2>/dev/null`" in - ?*) go=true; subtract size $size 1 ;; - *) go=false; add size $size 1 ;; - esac - ;; - esac - done - # now $size is the size of the first n-1 lines - # add $ed.c to $ed.b - ( $dd if=$ed.c; $dd if=$ed.b ) 2>/dev/null > $tmp.5 - $dd if=$tmp.5 of=$ed.b 2>/dev/null - # move line to ed.c - case "$size" in - 0) $dd if=$ed.a of=$ed.c 2>/dev/null - $dd if=/dev/null of=$tmp.5 2>/dev/null - ;; - *) $dd if=$ed.a of=$ed.c bs=1 skip=$size 2>/dev/null - $dd if=$ed.a of=$tmp.5 bs=1 count=$size 2>/dev/null - ;; - esac - # move rest to ed.a - $dd if=$tmp.5 of=$ed.a 2>/dev/null - ;; - esac -} - -# goes to a given line -goto () { - rl="$1" - compare bla "$rl" $lineno - case "$bla" in - eq) return - ;; - gt) while gt "$rl" $lineno - do - next - done - ;; - lt) while lt "$rl" $lineno - do - prev - done - ;; - esac -} - -lineout () { - Echo -n "$lineno: " - $dd if=$ed.c 2>/dev/null -} - -state=closed -name= -autoprint=true - -while true -do - Echo -n '> ' - read cmd arg - case "$cmd:$state" in - open:open) Echo "There is a file open already" ;; - open:*) if open "$arg" - then state=open; name="$arg"; $autoprint - else Echo "Cannot open $arg" - fi - ;; - new:open) Echo "There is a file open already" ;; - new:*) open "$arg" - state=open - name="$arg" - $autoprint - ;; - close:changed) Echo "Use 'discard' or 'save'" ;; - close:closed) Echo "Closed already" ;; - close:*) state=closed ;; - save:closed) Echo "There isn't a file to save" ;; - save:*) case "$arg" in - ?*) save "$arg" ;; - *) save "$name" ;; - esac - state=open - ;; - discard:changed) Echo "Your problem!"; state=closed ;; - discard:*) state=closed ;; - print:closed) Echo "No current file" ;; - print:*) lineout ;; - goto:closed) Echo "No current file" ;; - goto:*) goto "$arg"; $autoprint ;; - next:closed) Echo "No current file" ;; - next:*) next; $autoprint ;; - prev:closed) Echo "No current file" ;; - prev:*) prev; $autoprint ;; - name:closed) Echo "No current file" ;; - name:*) name="$arg" ;; - replace:closed) Echo "No current file" ;; - replace:*) if rstring 1 $arg - then state=changed; $autoprint - else Echo "Not found" - fi - ;; - nreplace:closed) Echo "No current file" ;; - nreplace:*) if rstring $arg - then state=changed; $autoprint - else Echo "Not found" - fi - ;; - delete:closed) Echo "No current file" ;; - delete:*) delete; state=changed; $autoprint ;; - insert:closed) Echo "No current file" ;; - insert:*) insert "$arg"; prev; state=changed; $autoprint ;; - quit:changed) Echo "Use 'save' or 'discard'" ;; - quit:*) Echo "bye"; exit;; - autoprint:*) autoprint="lineout" ;; - noprint:*) autoprint="" ;; - :*) ;; - *) Echo "Command not understood" ;; - esac -done - |