ref: 25f9e2963d99c77c9c6c259820474c89076e0921
author: kvik <kvik@a-b.xyz>
date: Mon Jan 13 15:06:39 EST 2020
Slurp
--- /dev/null
+++ b/README
@@ -1,0 +1,5 @@
+# rc dump
+
+Mildly curated subset of my `$home/bin/rc`. Largely useless even to
+the author most of these scripts got checked in for archival purposes
+and may fall off the branch as we speak.
--- /dev/null
+++ b/bin/21
@@ -1,0 +1,11 @@
+#!/bin/rc
+# 21 - poor man's acme 2-1 chord for sam
+rfork e
+for(i in `{seq 1 $#*})+ args=($args ''''$$i'''')
+cat >/env/pgm <<'.'
+cd `{basename -d $%}+$* $"%s
+cat
+.
+window -m 'rc /env/pgm '$"args
--- /dev/null
+++ b/bin/9plumb
@@ -1,0 +1,20 @@
+#!/bin/rc
+# 9p://
+# type is text
+# data matches '9p://([^ /]+)(/[^ ]+)?'
+# plumb start window 9plumb $1 $2
+
+host=$1
+name=$2
+if(~ $#name 0)
+ name=''
+srv $host $host /n/$host
+if(~ $name '' || test -d /n/$host/$name){+ cd /n/$host/$name; pwd; ls -l
+}
+if not{+ cd `{basename -d /n/$host/$name}+ echo /n/$host/$name
+ cat /n/$host/$name
+}
+exec rc
--- /dev/null
+++ b/bin/Y
@@ -1,0 +1,12 @@
+#!/bin/rc
+# Yank [register]
+if(~ $#* 1){+ where=/env/$1
+ echo '>cat >>'$where
+}
+if not {+ where=/env/yXy
+ cat /dev/snarf >$where
+ echo '>cat >>'$where
+ echo '!cat $where >/dev/snarf'
+}
--- /dev/null
+++ b/bin/argz
@@ -1,0 +1,27 @@
+#!/bin/rc
+cat >/env/pgm <<.
+function parseflags( a, i) {+ while(ARGV[++argi] ~ /^-.+$/){+ if(ARGV[argi] == "--"){+ argi++
+ break
+ }
+ split(ARGV[argi], a, "")
+ if(length(a) == 2 && ARGV[argi+1] !~ /^-/){+ flag[a[2]] = ARGV[++argi]
+ continue
+ }
+ for(i = 1; i <= length(a); i++)
+ if(a[i] != "-")
+ flag[a[i]] = 1
+ }
+}
+BEGIN{+ parseflags()
+ for(f in flag)
+ print f " " flag[f]
+ for(; argi < ARGC; argi++)
+ print ARGV[argi]
+}
+.
+awk -f /env/pgm -- $*
--- /dev/null
+++ b/bin/bg
@@ -1,0 +1,5 @@
+#!/bin/rc
+# bg file
+ppid=`{cat /proc/$pid/ppid}+echo -n `{cat /proc/$ppid/noteid} > /proc/$pid/noteid+exec rc $1
--- /dev/null
+++ b/bin/c
@@ -1,0 +1,65 @@
+#!/bin/rc
+rfork e
+fn usage {>[2=1] echo 'usage:' $usage && exit 'usage'}+usage='c [-fs] [regex] [search]
+ -f find functions
+ -s find structs'
+
+fn struct {+ ignore = (/sys/include/ape)
+ search = $*
+ if(~ $#search 0)
+ search = (/sys/include .)
+ if(~ $search *^$ignore^*)
+ ignore = (cat)
+ if not
+ ignore = (grep -v -e^'^'$ignore)
+
+ files = `{walk -f $search | $ignore | grep '\.[chsyl]$'}+
+ echo 'X ,x@^struct([^}][^;]*\n*)+};\n@ g@^struct[ ]+'$regex'@ {+ !echo '•' $%:$%l
+ p
+ }' | sam -d $files >[2]/dev/null
+}
+
+fn function {+ ignore = ('\.root.s$' 'cmd/python/')+ search = $*
+ if(~ $#search 0)
+ search = (.)
+ if(~ $search *^$ignore^*)
+ ignore = (cat)
+ if not
+ ignore = (grep -v -e^'^'$ignore)
+
+ files = `{walk -f $search | $ignore | grep '\.[chsyl]$'}+
+ sep = ' • '
+ echo 'X ,x g@^'$regex'\(@ {+ !echo -n $%:$%l $sep
+ p
+ }' | sam -d $files >[2]/dev/null
+}
+
+identifier = '[a-zA-Z_0-9]*'
+op = (struct)
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case -f -func*
+ op = 'function'
+ case -s -struct
+ op = 'struct'
+ case *
+ usage
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+regex = `{echo $1 | sed 's:%:'$identifier':g'}+if(~ $#regex 0)
+ regex = $identifier
+shift
+
+$op $*
--- /dev/null
+++ b/bin/c+
@@ -1,0 +1,8 @@
+#!/bin/rc
+switch($%){+case *.[chs] *.myr
+ cmnt='//'
+case *
+ cmnt='#'
+}
+exec sed 's,^,'$cmnt','
--- /dev/null
+++ b/bin/c-
@@ -1,0 +1,8 @@
+#!/bin/rc
+switch($%){+case *.[chs] *.myr
+ cmnt='//'
+case *
+ cmnt='#'
+}
+exec sed 's,^'$cmnt',,'
--- /dev/null
+++ b/bin/cc
@@ -1,0 +1,8 @@
+#!/bin/rc
+
+rfork e
+
+O=`{sed 's/^O=//; t end; D; :end; q' /$objtype/mkfile}+CFLAGS=`{sed 's/^CFLAGS=//; t end; D; :end; q' /sys/src/mkfile.proto}+
+$O^c $CFLAGS $1.c && $O^l -o $1 $1.$O
--- /dev/null
+++ b/bin/cin
@@ -1,0 +1,22 @@
+#!/bin/rc
+rfork e
+nl='
+'
+while(line=`$nl{read}){+ cmd=$line
+ if(~ $#cmd 0) cmd='\r'
+ switch($cmd){+ case '\r'
+ ci /env/code
+ case '\t'
+ time ci /env/code
+ case '\prof'
+ ci -p /env/code
+ case '\p'
+ cat /env/code
+ case '\c'
+ >/env/code
+ case *
+ echo $line >>/env/code
+ }
+}
--- /dev/null
+++ b/bin/clear
@@ -1,0 +1,7 @@
+#!/bin/rc
+if(~ $1 -a){+ >/dev/text
+ exit
+}
+</dev/text sed '/^'^$prompt(1)^'/q' | sed '$d' >/tmp/clear
+cat /tmp/clear >/dev/text
--- /dev/null
+++ b/bin/crap
@@ -1,0 +1,118 @@
+#!/bin/rc
+# crap [ -s sandbox ]
+# commands:
+# empty line executes
+# p, P - print code / sandbox
+# c, C - clear code / sandbox
+# e, E - open $editor on code / sandbox
+# s - print assembly listing
+# d - run acid(1)
+# t - run time(1)
+
+rfork en
+
+if(~ $#editor 0)
+ editor=(ed)
+nl='
+'
+tab=' '
+sandbox0=sandbox0.$pid.c
+sandbox=sandbox.$pid.c
+tmp=tmp.$pid.c
+util=util.$pid.h
+code=code.$pid.c
+mkfile=mkfile.$pid
+
+fn generate {+ <$sandbox >$tmp ssam '
+ /\/\*START\*\//+1 , /\/\*END\*\//-1 c/\n/
+ /\/\*START\*\//+1 r '$code
+ cp $tmp $sandbox
+}
+
+ramfs -bc -m .
+
+>$mkfile echo '
+</$objtype/mkfile
+CFLAGS=-FTVN
+default:VQ:
+ $CC $CFLAGS -o sandbox.$O '^$sandbox^'
+ $LD $LDFLAGS sandbox.$O
+asm:VQ:
+ $CC $CFLAGS -S '^$sandbox^'
+run:VQ: default
+ ./$O.out
+time:VQ: default
+ time ./$O.out'
+
+>$util echo '
+char errmsg[ERRMAX];
+#define err \
+ rerrstr(errmsg, ERRMAX); \
+ if(errmsg[0] != 0) print("error: %r\n");+#define fail \
+ rerrstr(errmsg, ERRMAX); \
+ if(errmsg[0] != 0) sysfatal("%r");'+
+>$sandbox0 echo '
+#include <u.h>
+#include <libc.h>
+#include "'^$util^'"
+void
+main(int, char *[])
+{+ /*START*/
+
+ /*END*/
+ exits(nil);
+}'
+
+while(! ~ $#* 0 && ~ $1 -* && ! ~ $1 --){+ switch($1){+ case -s
+ cp $2 $sandbox0
+ shift
+ }
+ shift
+}
+cp $sandbox0 $sandbox
+
+echo -n >$code
+while(line=`$nl{read}){+ if(! echo $"line | grep -s '^.$' && ! ~ $#line 0){+ echo -n $"tab >>$code
+ echo $"line >>$code
+ }
+ if not{+ cmd=$line
+ switch($cmd){+ case s
+ generate
+ mk -f $mkfile asm
+ case d
+ generate
+ mk -f $mkfile run
+ acid *.out
+ case t
+ generate
+ mk -f $mkfile time
+ case e
+ $editor $code
+ case E
+ $editor $sandbox
+ <$sandbox >$code ssam -n '/\/\*START\*\//+1 , /\/\*END\*\//-1 p'
+ case p
+ cat $code
+ case P
+ cat $sandbox
+ case c
+ echo >$code
+ generate
+ case C
+ cp $sandbox0 $sandbox
+ case *
+ generate
+ mk -f $mkfile run
+ }
+ }
+}
--- /dev/null
+++ b/bin/enum
@@ -1,0 +1,29 @@
+#!/bin/rc
+rfork e
+fn usage{+ echo usage: `{basename $0} '[file ...]' >[1=2]+ exit 'usage'
+}
+
+if(! ~ $#* 0)
+ fl=$*
+if not
+ fl=(/sys/src/libc/^(port 9sys)^/*.c)
+
+awk '
+ /^enum[ ]*{$/ {+ matched = 1
+ if(nfound++ > 0)
+ print ""
+ if(ARGC != 1)
+ print FILENAME ":" FNR
+ }
+
+ matched {+ }
+
+ matched && /^}/ {+ matched = 0
+ }
+' $fl
--- /dev/null
+++ b/bin/ep
@@ -1,0 +1,22 @@
+#!/bin/rc -e
+rfork e
+fn usage {>[1=2] echo 'usage:' $usage && exit 'usage'}+usage='ep'
+
+fn salt {dd -if /dev/random -count 1 -quiet 1 | sum | sed 's/ .*//'}+
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case *
+ usage
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+if(test $#* -gt 0)
+ usage
+
+file = /tmp/ep.`{salt}+cat >$file
+plumb -d edit $file
--- /dev/null
+++ b/bin/escape
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec sed 's,([.*?+()|^$\-\[\]\\]),\\\1,g'
--- /dev/null
+++ b/bin/fakeroot
@@ -1,0 +1,6 @@
+#!/bin/rc
+bind / /n/realroot
+ramfs -m /n/portroot
+unionfs -m /n/root / -c /n/portroot
+bind /n/root /
+bind -c '#e' /env
--- /dev/null
+++ b/bin/find
@@ -1,0 +1,42 @@
+#!/bin/rc -e
+rfork e
+fn usage {>[2=1] echo 'usage:' $usage && exit 'usage'}+usage='find [-e regex ...] [type]'
+
+namefilters=()
+typefilters=(c rc)
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case -e
+ namefilters=($namefilters $2)
+ shift
+ case *
+ usage
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+if(~ $#namefilters 0)
+ namefilters=('.*')+if(test $#* -gt 0)
+ typefilters=$*
+select=''
+for(t in $typefilters)
+ select=$select^:^$t
+
+file `{walk -f | grep -e^$namefilters} | awk -F':' '+ BEGIN {+ split(ENVIRON["select"], select, ":")
+ delete select[1]
+ }
+ {+ sub(/^ */, "", $2)
+ for(s in select){+ if($2 ~ "^" select[s]){+ print $1
+ break
+ }
+ }
+ }
+'
--- /dev/null
+++ b/bin/func
@@ -1,0 +1,35 @@
+#!/bin/rc
+# func - find C function definitions
+# func [pattern]
+
+rfork e
+
+fn sigint sighup sigexit {+ rm -f $matches
+ exit
+}
+
+ignore='(\.root.s$)|(cmd/python/)'
+matches=/tmp/matches.$pid
+ident='([a-zA-Z_][a-zA-Z_0-9]*)'
+
+func=$1
+func=`{echo $func | sed 's,%,'$ident'?,g'}+if(~ $#func 0)
+ func=$ident
+#patt='^([^ ]+[ ]+)*'$func'\('+patt='^'$func'\('+
+srcs=`{walk -f | grep '\.[chs]$' | grep -v $ignore}+>$matches grep -n $patt $srcs /dev/null
+n=`{wc -l $matches}+switch($n(1)){+ case 0
+ exit 'no match'
+ case 1
+ plumb `{<$matches sed 's,: .*,,'}+ exit
+ case *
+ window -m 'cat '$matches'; cat'
+ sleep 1
+}
--- /dev/null
+++ b/bin/gridup
@@ -1,0 +1,137 @@
+#!/bin/rc
+rfork e
+fn usage {+ >[2=1] echo 'usage:' $0 '[-mst]'
+ exit usage
+}
+fn quiet {+ if(~ $quiet 'no')
+ >[2=1] echo $*
+}
+fn fail {+ quiet fail: $*
+ exit 'fail: '$*
+}
+
+registry='tcp!registry.9gridchan.org!6675'
+reconnect='no'
+mountonly='no'
+scriptonly='no'
+tls='no'
+quiet='no'
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case -m
+ mountonly='yes'
+ case -s
+ scriptonly='yes'
+ case -t
+ tls='yes'
+ registry='tcp!registry.9gridchan.org!6675'
+ case -q
+ quiet='yes'
+ reconnect='yes'
+ case *
+ usage
+ }
+ shift
+}
+if(! ~ $#* 0)
+ usage
+
+services=( \
+ gridregistry pubregistry \
+ gridchat gridplumber \
+ gridram griddisk \
+ gridroot gridwiki)
+for(s in $services)
+ if(test -w /srv/$s)
+ reconnect='yes'
+if(~ $reconnect 'yes'){+ if(~ $quiet 'no'){+ echo -n 'old grid connections found in /srv, remove? [y/n]: '
+ reconnect=`{read}+ }
+ if(~ $reconnect y*)
+ rm -f /srv/^$services
+}
+
+if(~ $mountonly 'no')
+ rfork n
+if(~ $tls 'no')
+ srv $registry gridregistry /mnt/registry || fail registry
+if not{+ if(! test -w /mnt/factotum/ctl)
+ auth/factotum
+ >/mnt/factotum/ctl echo 'key proto=dp9ik user=glenda dom=grid !password=9gridchan' || fail factotum
+ srvtls $registry gridregistry /mnt/registry || fail registry
+}
+
+>/tmp/gridmount echo '#!/bin/rc'
+>>/tmp/gridmount </mnt/registry/index awk -v 'tls='$tls '
+ /service tlssrv/ && tls == "yes" {+ print "srvtls -c", $1, $3, $5}
+ /service \/bin\/exportfs/ && tls == "no" {+ print "srv -c", $1, $3, $5}
+'
+chmod +x /tmp/gridmount
+
+if(~ $scriptonly 'yes'){+ quiet 'mount script saved in /tmp/gridmount'
+ cat /tmp/gridmount
+ exit
+}
+if(~ $mountonly 'yes'){+ /tmp/gridmount || fail 'could not mount'
+ quiet 'grid services mounted'
+ exit
+}
+
+>/tmp/chatcat cat <<'...'
+#!/bin/rc
+label chat
+echo 'README:'
+echo ' This is chatcat(1).'
+echo ' Type a (multi-line) message ending with a newline'
+echo ' and press control-d (EOT) to send.'
+echo
+echo -n 'nick? '
+nick=`{read}+if(~ $#nick 0)
+ nick='unknown gridster'
+echo JOIN $nick to chat >>/n/chat/chat
+cat /n/chat/chat &
+while() cat | sed '1s/^/'$nick' → /' >>/n/chat/chat
+...
+chmod +x /tmp/chatcat
+
+>/tmp/gridrio cat <<'...'
+#!/bin/rc
+if(test -x /bin/chat)
+ window -r 0 0 700 400 -scroll chat
+if not
+ window -r 0 0 700 400 -scroll /tmp/chatcat
+window -r 700 0 1300 400 acme -c1 /n/griddisk /n/griddisk/gridmsg
+window -r 0 400 700 750 mothra -a http://wiki.9gridchan.org/message_board
+window -r 700 400 1300 750 page /n/gridroot/lib/musicant.png
+...
+chmod +x /tmp/gridrio
+
+>/tmp/gridscript cat <<'...'
+#!/bin/rc
+/tmp/gridmount
+fn cpl {+ cp $1 /n/griddisk/cpl
+ ptarg=`{basename $1}+ plumb http://wiki.9gridchan.org/incoming/cpl/$ptarg
+}
+if(! test -e /mnt/web/ctl)
+ webfs
+rio=(rio)
+if(test -x /bin/grio)
+ rio=(grio -c 0x99009900)
+exec $rio -i /tmp/gridrio
+...
+chmod +x /tmp/gridscript
+
+window -r 0 0 1350 750 /tmp/gridscript
--- /dev/null
+++ b/bin/hd
@@ -1,0 +1,16 @@
+#!/bin/rc
+lines=3
+while(! ~ $#* 0 && ~ $1 -* && ! ~ $1 --){+ switch($1){+ case -[0-9]*
+ lines=`{echo $1 | sed 's:^-::'}+ }
+ shift
+}
+if(~ $1 --)
+ shift
+if(~ $#* 0)
+ '*'=*
+for(f)
+ if(test -f $f)
+ echo « $f && sed $lines^q $f && echo »
--- /dev/null
+++ b/bin/hist
@@ -1,0 +1,14 @@
+#!/bin/awk -f
+function rep(s, n, t) {+ n = int(n / (max+1) * 60)
+ while (n--)
+ t = t s
+ return t
+}
+{ x[int($1/10)]++ }+END {+ for (i = 0; i < 10; i++)
+ if (x[i] > max) max = x[i]
+ for (i = 0; i < 10; i++)
+ printf("%-10d - %s\n", x[i], rep("*", x[i]))+}
--- /dev/null
+++ b/bin/hublog
@@ -1,0 +1,7 @@
+#!/bin/rc
+if(! test -e /srv/hublog)
+ hubfs -t -s hublog
+local mount -c /srv/hublog /mnt/log
+if(! test -e /mnt/log/log)
+ touch /mnt/log/log
+cat /mnt/log/log
--- /dev/null
+++ b/bin/i+
@@ -1,0 +1,9 @@
+#!/bin/awk -f
+BEGIN{+ tabs = " "
+ if(ARGC > 1){+ n = ARGV[1]; ARGC--
+ while(--n) tabs = tabs " "
+ }
+}
+{ print tabs $0 }--- /dev/null
+++ b/bin/i-
@@ -1,0 +1,17 @@
+#!/bin/awk -f
+BEGIN{+ n = 1
+ if(ARGC > 1){+ n = ARGV[1]; ARGC--
+ }
+ for(i = 1; i < 50; i++)
+ tabs[i] = tabs[i-1] " "
+}
+{+ if(match($0, /^ +/) == 0){+ next
+ }
+ sub(/^ +/, tabs[RLENGTH-n])
+}
--- /dev/null
+++ b/bin/ipatch
@@ -1,0 +1,21 @@
+#!/bin/rc
+rfork e
+fn usage {+ >[2=1] echo $0 f1 f2
+ exit usage
+}
+
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case *
+ usage
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+if(! ~ $#* 2)
+ usage
+
+cp $1 $1.orig &&
+idiff $1.orig $2 > $1
--- /dev/null
+++ b/bin/isatty
@@ -1,0 +1,6 @@
+#!/bin/awk -f
+BEGIN {+ getline <"/fd/0ctl"
+ if($10 != "/dev/cons")
+ exit "nein"
+}
--- /dev/null
+++ b/bin/j
@@ -1,0 +1,8 @@
+#!/bin/rc
+# Join lines
+exec ssam '
+,x~.*\n~{+ x~^[ ]+~d
+ x~[ ]+$~d
+}
+,x~\n~c~ ~'
--- /dev/null
+++ b/bin/joynes
@@ -1,0 +1,45 @@
+#!/bin/rc
+nusb/joy $1 | awk -safe -v 'joy='$2 '
+ BEGIN { k[0] = "" }+
+# /^axis 0 0/ { k[0] = "left " }+# /^axis 0 255/ { k[0] = "right " }+# /^axis 0 128/ { k[0] = "" }+#
+# /^axis 1 0/ { k[1] = "up " }+# /^axis 1 255/ { k[1] = "down " }+# /^axis 1 128/ { k[1] = "" }+
+ /^down 5$/ { k[0] = "up " }+ /^down 6$/ { k[0] = "right " }+ /^down 7$/ { k[0] = "down " }+ /^down 8$/ { k[0] = "left " }+
+ /^down 9$/ { k[3] = "b " }+ /^down 10$/ { k[2] = "a " }+ /^down 16$/ { k[3] = "b " }+ /^down 14$/ { k[2] = "a " }+ /^down 1$/ { k[4] = "control " }+ /^down 4$/ { k[5] = "start " }+
+ /^up 5$/ { k[0] = "" }+ /^up 6$/ { k[0] = "" }+ /^up 7$/ { k[0] = "" }+ /^up 8$/ { k[0] = "" }+
+ /^up 9$/ { k[3] = "" }+ /^up 10$/ { k[2] = "" }+ /^up 16$/ { k[3] = "" }+ /^up 14$/ { k[2] = "" }+ /^up 1$/ { k[4] = "" }+ /^up 4$/ { k[5] = "" }+
+ /^up|down/ {+ if(joy != "")
+ printf "joy%s ", joy
+ for(i = 0; i <= 5; i++)
+ printf k[i]
+ printf "\n"
+ fflush
+ }
+'
--- /dev/null
+++ b/bin/k
@@ -1,0 +1,27 @@
+#!/bin/rc
+# k - mark position (from sam)
+
+marks=$ws/marks
+if(~ $#marks 0)
+ marks=/tmp/marks.default
+
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case -c
+ >$marks; exit
+ case -p
+ plumb -d edit $marks
+ case -v
+ test -f $marks && window 'label marks; tail -f '$marks
+ exit
+ case *;
+ exit usage
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+
+if(~ $#% 0)
+ exit notsam
+echo $%:$'%l' $* >>$marks
--- /dev/null
+++ b/bin/kprint
@@ -1,0 +1,6 @@
+#!/bin/rc
+w h 0.2 Down Right
+>/dev/text
+label /dev/kprint
+echo scroll > /dev/wctl
+cat /dev/kprint
--- /dev/null
+++ b/bin/last
@@ -1,0 +1,21 @@
+#!/bin/rc
+
+# Repeats on standard output the textual output
+# of the last command in a current rio window.
+# May be considered a complement to "(1).
+
+awk '
+ /^'^$prompt(1)^'/ {clear = 1; next}+ {+ if(clear){+ clear = 0
+ i = 0
+ delete buf
+ }
+ buf[i++] = $0
+ }
+ END{+ for(i=0; i<length(buf); i++)
+ print buf[i]
+ }
+' /dev/text
--- /dev/null
+++ b/bin/lc
@@ -1,0 +1,10 @@
+#!/bin/rc
+rfork en
+d=/n/ram
+f=$d/list
+
+ramfs -m $d
+ls -pF $* >$f
+
+grep '/$' $f | mc
+grep -v '/$' $f | mc
--- /dev/null
+++ b/bin/live
@@ -1,0 +1,60 @@
+#!/bin/rc
+# live 'grep ~ *'
+# tilde will be replaced by the typed text, enter runs the
+# command. there's a very limited line-editing in the form
+# of backspace, and ^W and ^U, which just kill the whole line.
+rfork e
+bs=''
+cu=''
+cw=''
+del=''
+nl=`{unicode -t 0x0a}+cmd0=$1
+cmd=echo
+killme=please
+fn prep {+ n=`{wc -c /env/buf}+ if(! ~ $n(1) 0){+ cmd=`{echo $cmd0 | sed 's/~/'^`{cat /env/buf}^'/'}+ echo -n $cmd
+ }
+ if not
+ echo -n $cmd0
+}
+fn run {+ echo $cmd
+ @{eval $cmd} &+ killme=$apid
+}
+fn stop {+ if(test -f /proc/$killme/notepg)
+ echo kill >/proc/$killme/notepg
+}
+>/env/buf
+>/dev/text
+echo scroll >/dev/wctl
+>[3]/dev/consctl </dev/cons {+ echo rawon >[1=3]
+ while(c=`{read -c 1}){+ >/dev/text
+ switch($c){+ case $"nl
+ run
+ case $del
+ stop
+ exit
+ case $cw $cu
+ stop
+ >/env/buf
+ prep
+ case $bs
+ stop
+ read -c `{echo `{wc -c </env/buf} - 1 | bc} </env/buf >/env/tmp+ cp /env/tmp /env/buf
+ prep
+ case *
+ echo -n $"c >>/env/buf
+ prep
+ }
+ }
+}
--- /dev/null
+++ b/bin/loc
@@ -1,0 +1,21 @@
+#!/bin/rc
+# Print the address of a selection in acme
+nl='
+'
+w=/mnt/acme/$winid
+tag=`{cat $w/tag}+fn regexaddr {+ echo 'addr=dot' >$w/ctl
+ sel=`$nl{escape <$w/xdata}+ addr=$tag(1)^':/^'$sel
+ echo $addr
+}
+fn charaddr {+ echo 'addr=dot' >$w/ctl
+ addr=`{cat <$w/addr}+ echo $tag(1)^':#'^$addr(1)^',#'^$addr(2)
+}
+addrfn=regexaddr
+if(test $#* -gt 0 && ~ $1 -c)
+ addrfn=charaddr
+$addrfn
--- /dev/null
+++ b/bin/local
@@ -1,0 +1,21 @@
+#!/bin/rc -e
+
+if(~ $#ws 0)
+ ws=/tmp
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case -r
+ . $ws/mounts
+ plumb 'Local . '$ws'/mounts'
+ exit
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+
+echo $"* >>$ws/mounts
+uniq $ws/mounts >$ws/mounts.q
+mv $ws/mounts.q $ws/mounts
+
+eval $* && plumb 'Local '$"*
--- /dev/null
+++ b/bin/lsman
@@ -1,0 +1,6 @@
+#!/bin/rc
+sect=1
+if(test $#* -gt 0)
+ sect=$*
+for(s in $sect)
+ ls /sys/man/$s | sed '/(INDEX|NOTICE)/d; s/^.*\///g; s/.*/&\('$s'\)/g' | mc--- /dev/null
+++ b/bin/mkfont
@@ -1,0 +1,29 @@
+#!/bin/rc
+fn usage {>[1=2] echo 'usage:' $usage && exit 'usage'}+usage='mkfont [-s sizes] [-m method] fontname'
+
+rfork e
+method=antialias
+sz=(14 16 18 20)
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case -m
+ method=$2; shift
+ case -s
+ sz=$2; shift
+ case *
+ usage
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+if(~ $#* 0)
+ usage
+fntname=$1
+shift
+fntfile=$fntname.ttf
+if(~ $#* 1)
+ fntfile=$1
+for(s in $sz)
+ ttf2subf -s $s -f $fntfile -n $fntname -m $method
--- /dev/null
+++ b/bin/mkservice
@@ -1,0 +1,25 @@
+#!/bin/rc
+rfork e
+fn usage {>[1=2] echo 'usage:' $usage && exit 'usage'}+usage='mkservice path'
+
+svpath = $1
+if(~ $#svpath 0)
+ usage
+svname = `{basename $svpath}+cat <<. |x/run
+ set -e
+ mkdir -p $svpath
+ cd $svpath
+ touch run
+ chmod +x run
+ echo '#!/bin/sh' >>run
+ echo 'exec 2>&1' >>run
+ echo 'exec sleep 10' >>run
+
+ mkdir log
+ touch log/run
+ chmod +x log/run
+ echo '#!/bin/sh' >>log/run
+ echo 'exec logger -t $svname -p daemon.notice' >>log/run
+.
--- /dev/null
+++ b/bin/mktxt
@@ -1,0 +1,5 @@
+#!/bin/rc
+f=/fd/0
+if(test $#* -gt 0)
+ f=$*
+troff -man -N -rL1000i $f | ssam 'x/\n\n\n+/c/\n\n/'
--- /dev/null
+++ b/bin/mnt
@@ -1,0 +1,54 @@
+#!/bin/rc
+
+fn usage {+ >[1=2] {+ echo mnt [mount options] [-m mtpt] [-s spec] name cmd [args ...]
+ echo mnt [mount options] [-m mtpt] [-s spec] name
+ }
+ exit usage
+}
+
+flags=()
+mtpt=()
+spec=()
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case -m
+ mtpt=$2
+ shift
+ case -s
+ spec=$2
+ shift
+ case *
+ flags=($flags $1)
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+name=$1
+if(~ $#name 0)
+ usage
+shift
+if(~ $#mtpt 0)
+ mtpt=/n/$name
+cmd=$1
+if(! ~ $#cmd 0)
+ shift
+
+if(mount $flags /srv/$name $mtpt $spec )
+ exit
+if(~ $#cmd 0)
+ usage
+switch($cmd){+case srv srvtls
+ $cmd $* $name
+case rimport
+ rimport $flags -s $name $* $mtpt
+ exit
+case ramfs
+ ramfs -S $name $*
+case *
+ $cmd -s $name $*
+}
+mount $flags /srv/$name $mtpt $spec
--- /dev/null
+++ b/bin/new
@@ -1,0 +1,37 @@
+#!/bin/rc -e
+rfork e
+fn usage {>[1=2] echo 'usage:' $usage && exit 'usage'}+usage='new [file]'
+
+mode = 755
+skeldir = $home/skel
+skel = $skeldir/rc
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case -m
+ mode = $2
+ shift
+ case --*
+ skel = $skeldir/`{echo $1 | sed 's/^--//'}+ }
+ shift
+}
+if(~ $1 --)
+ shift
+
+files = $*
+if(~ $#files 0)
+ files =`{fortune <{</lib/words awk 'length($0) == 3 {print tolower($0)}'}}+
+for(f in $files){+ if(~ $f */*)
+ mkdir -p `{echo $f | sed 's@(.*)/.*$@\1@'}+ if(test -e $f)
+ >[1=2] echo 'file exists:' $f
+ if not{+ echo $f
+ cat $skel >$f
+ chmod $mode $f
+ plumb -d edit $f
+ }
+}
--- /dev/null
+++ b/bin/nsec
@@ -1,0 +1,2 @@
+#!/bin/ci
+print("%lld\n", nsec());--- /dev/null
+++ b/bin/nu
@@ -1,0 +1,2 @@
+#!/bin/awk -f
+{printf("%d\t%s\n", NR, $0)}--- /dev/null
+++ b/bin/p
@@ -1,0 +1,6 @@
+#!/bin/rc
+# put [register]
+where=/dev/snarf
+if(! ~ $#* 0)
+ where=/env/$1
+echo '<cat '$where
--- /dev/null
+++ b/bin/paste
@@ -1,0 +1,18 @@
+#!/bin/rc -e
+rfork en
+fn usage {+ >[2=1] echo $0
+ exit usage
+}
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case *
+ usage
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+9fs www
+for(a)
+ cp $a /n/www/tmp
--- /dev/null
+++ b/bin/pfx
@@ -1,0 +1,9 @@
+#!/bin/rc
+args=()
+for(arg){+ if(echo $arg | grep -s '[ ]')
+ args=($args ''''$arg'''')
+ if not
+ args=($args $arg)
+}
+sed 's:^:'^$"args^' :g'
--- /dev/null
+++ b/bin/pins
@@ -1,0 +1,14 @@
+#!/bin/rc
+dir=$1
+if(~ $#dir 0)
+ dir='out'
+</dev/audiostat awk '
+/^pin [0-9]+ '$dir'/ {+ printf "@{echo pin %d>/dev/audioctl} #", $2+ for(i = 4; i <= NF; i++){+ if($i == "←")
+ break
+ printf " %s", $i
+ }
+ printf "\n"
+}'
--- /dev/null
+++ b/bin/plumb.dir
@@ -1,0 +1,21 @@
+#!/bin/rc
+rfork e
+fn usage {+ >[2=1] echo $0
+ exit usage
+}
+
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case *
+ usage
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+
+t=/dev/wsys/`{cat $wsdir/target}^/text+echo cd $1 >/tmp/text
+cat $t >>/tmp/text
+cp /tmp/text $t
--- /dev/null
+++ b/bin/pwds
@@ -1,0 +1,3 @@
+#!/bin/rc
+cat /dev/text >/tmp/xxx
+cat <{echo -n 'cd '; pwd} /tmp/xxx >/dev/text--- /dev/null
+++ b/bin/raiseplumb
@@ -1,0 +1,20 @@
+#!/bin/rc
+rfork e
+
+fn usage {+ echo $0 port >[1=2]
+ exit usage
+}
+
+port=$1
+if(~ $#port 0)
+ usage
+{+ while(read -c 1 /mnt/plumb/$port >/dev/null){+ >/dev/wctl >[2]/dev/null {+ echo -n current
+ echo -n unhide
+ }
+ }
+} &
+echo -n `{cat /proc/$pid/noteid} > /proc/$apid/noteid--- /dev/null
+++ b/bin/rand
@@ -1,0 +1,9 @@
+#!/bin/awk -f
+BEGIN {+ srand()
+ n = 1
+ if(ARGC == 2)
+ n = ARGV[1]
+ for(i = 0; i < n; i++)
+ print int(rand()*100)
+}
--- /dev/null
+++ b/bin/rawwer
@@ -1,0 +1,21 @@
+#!/bin/rc
+rfork e
+fn usage {>[1=2] echo 'usage:' $usage && exit 'usage'}+usage='rawwer cmd'
+
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case *
+ usage
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+cmd = $*
+if(~ $#cmd 0)
+ usage
+>[3]/dev/consctl </dev/cons{+ echo rawon >[1=3]
+ exec $cmd
+}
--- /dev/null
+++ b/bin/recv
@@ -1,0 +1,12 @@
+#!/bin/rc
+fn usage {+ >[2=1] echo 'recv port [file]'
+ exit usage
+}
+port=$1
+if(~ $#port 0)
+ usage
+file=$2
+if(~ $#file 0)
+ file=/fd/1
+>[9=1] >[9]$file aux/listen1 -t tcp!*!$port rc -c '/bin/cat >[1=9]'
--- /dev/null
+++ b/bin/regidx
@@ -1,0 +1,6 @@
+#!/bin/rc
+mtpt=/mnt/registry
+if(test $#* -gt 0)
+ mtpt=$1
+awk '/tlssrv/{print "srvtls -c", $1, $3, $5}+/exportfs/{print "srv -c", $1, $3, $5 }' $mtpt/index--- /dev/null
+++ b/bin/rfc
@@ -1,0 +1,42 @@
+#!/bin/rc
+rfork e
+fn usage {+ >[2=1] echo $0
+ exit usage
+}
+
+cmd='search'
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case -s
+ cmd='search'
+ case *
+ usage
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+
+fn cleanupindex {+ </lib/rfc/rfc-index awk '
+ /^ +RFC INDEX/ {i++; l = NR}+ i >= 2 && NR > l+4 {print}+ '
+}
+
+fn search {+ query=$1
+ cleanupindex | awk '
+ BEGIN {RS=""}+ /'$query'/ {+ num = $1
+ sub(/^0+/, "", num)
+ print "RFC" num
+ sub(/^..../, " ", $0)
+ print $0
+ }
+ '
+}
+
+$cmd $*
--- /dev/null
+++ b/bin/rn
@@ -1,0 +1,8 @@
+#!/bin/rc
+from=$1
+to=$2
+charconst='''[^'']*'''
+strconst='"([^"]|\\")*"'
+name='[a-zA-Z_][a-zA-Z_0-9]*'
+partial=.^`{echo -n $from | tr -c '' .}+exec ssam 'y/'$charconst'/ y/'$strconst'/ x/'$name'/ g/'$from'/ v/'$partial'/ c/'$to
--- /dev/null
+++ b/bin/rs
@@ -1,0 +1,2 @@
+#!/bin/rc
+grep softscreen /dev/vgactl >/dev/vgactl
--- /dev/null
+++ b/bin/rwin
@@ -1,0 +1,12 @@
+#!/bin/rc
+rfork en
+if(test -f /mnt/acme/index){ # in acme+ unmount /acme/bin/amd64 /bin
+ unmount /acme/bin /bin
+ tag=`{cat /mnt/acme/$winid/tag}+ dir=`{basename -d $tag(1)}+}
+if not{ # in sam+ dir=`{basename -d $%}+}
+exec window -m -cd $dir $*
--- /dev/null
+++ b/bin/samchat
@@ -1,0 +1,14 @@
+#!/bin/rc
+chan=/n/chat/chat
+bind '#|' /mnt/samchat
+data=/mnt/samchat/data1
+{+ while(){+ <$data >>$chan ssam '
+ 1 x/^/ c/'$user' : /
+ ,s/\n\n\n+/\n\n/g
+ $-2,$-1 s/\n\n/\n/
+ $-#1,$ v/\n/ a/\n/'
+ }
+} &
+echo `{cat /proc/$pid/noteid} >/proc/$apid/noteid--- /dev/null
+++ b/bin/samcmd
@@ -1,0 +1,16 @@
+#!/bin/awk -f
+BEGIN{+ plumb = "plumb -i -d edit -a 'action=Edit'"
+ if(ARGC > 1){+ for(i = 1; i < ARGC; i++)
+ cmd = cmd " " ARGV[i]
+ print cmd | plumb
+ exit
+ }
+}
+{+ if($1 == "!")
+ $0 = last
+ print | plumb; close(plumb)
+ last = $0
+}
--- /dev/null
+++ b/bin/samv
@@ -1,0 +1,17 @@
+#!/bin/rc
+# samv [-m] [samflags] [file ...]
+rfork e
+flags=(-a)
+while(~ $1 -*){+ switch($1){+ case *
+ flags=($flags $1)
+ }
+ shift
+}
+files=($%)
+if(! ~ $#* 0)
+ files=($files $*)
+cmd=(sam $flags $files)
+#ptrap edit $"files
+window -m $cmd
--- /dev/null
+++ b/bin/scr
@@ -1,0 +1,6 @@
+#!/bin/rc
+rfork e
+dst=/tmp/scr.png
+if(! ~ $#* 0)
+ dst=$1
+topng /dev/screen >$dst
--- /dev/null
+++ b/bin/scratch
@@ -1,0 +1,7 @@
+#!/bin/rc
+if(test $#* -ge 1){+ >$1
+ window -m hold $1
+}
+if not
+ window hold
--- /dev/null
+++ b/bin/share
@@ -1,0 +1,53 @@
+#!/bin/rc
+# share - share files with the grid
+# Uploads a given file to a shared griddisk (gridram with -r)
+# directory and plumbs the resulting file path (web url with -w).
+# Option -n disables plumbing.
+rfork en
+fn usage{+ echo share [-rwn] file [destdir] >[1=2]
+ exit usage
+}
+plumb='yes'
+urlplumb='no'
+dest='griddisk'
+if(~ $#* 0) usage
+while(! ~ $#* 0 && ~ $1 -*){+ switch($1){+ case -n
+ plumb='no'
+ case -r
+ dest='gridram'
+ urlplumb='no'
+ case -w
+ dest='griddisk'
+ urlplumb='yes'
+ case *
+ usage
+ }
+ shift
+}
+switch($dest){+ case gridram
+ destdir=''
+ case griddisk
+ destdir='tmp'
+}
+if(~ $#* 2)
+ destdir=$2
+file=$1
+destpath=/n/$dest/$destdir
+if(! test -d $destpath)
+ mkdir -p $destpath
+fcp $file $destpath
+if(~ $plumb no)
+ exit
+if(test -e /srv/gridplumber)
+ mount /srv/gridplumber /mnt/plumb
+if(~ $urlplumb no)
+ plumb $destpath/`{basename $file}+if not {+ url='http://wiki.9gridchan.org/incoming/'$destdir/`{basename $file}+ echo $url
+ plumb $url
+}
--- /dev/null
+++ b/bin/shr
@@ -1,0 +1,14 @@
+#!/bin/rc
+fn die {>[1=2] echo $*; exit $"*}+fn usage {>[1=2] echo 'usage:' $usage && exit 'usage'}+usage='shr srv [name]'
+if(~ $#* 0)
+ usage
+srv=$1
+name=$srv
+if(~ $#* 2)
+ name=$2
+if(! test -e /srv/$srv)
+ die 'service does not exist:' $srv
+mkdir '#σc'/$name
+<>[3]/srv/$srv >'#σc'/$name/$srv echo 3
--- /dev/null
+++ b/bin/sio
@@ -1,0 +1,30 @@
+#!/bin/rc -e
+rfork e
+overwrite=no
+data=/tmp/sio.$pid
+>$data
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case -i
+ cat >$data
+ case -f
+ overwrite=yes
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+if(! ~ $#* 0){+ switch($1){+ case /*
+ ndata=$1
+ case *
+ ndata=/tmp/sio.$1
+ }
+ if(~ $overwrite yes)
+ mv $data $ndata
+ data=$ndata
+}
+
+sam -a $data
+cat $data
--- /dev/null
+++ b/bin/snarfy
@@ -1,0 +1,5 @@
+#!/bin/rc
+rfork n
+aux/stub /mnt/snarfy/snarf
+bind -c /dev/snarf /mnt/snarfy/snarf
+aux/listen1 -t tcp!*!2000 /bin/exportfs -r /mnt/snarfy &
--- /dev/null
+++ b/bin/sparse
@@ -1,0 +1,7 @@
+#!/bin/rc
+if(~ $#* 0)
+ exit 'usage'
+name=$1
+shift
+sz=$*
+dd -if /dev/zero -of $name -seek `{sz $sz} -bs 1 -count 1--- /dev/null
+++ b/bin/srvq
@@ -1,0 +1,23 @@
+#!/bin/rc
+rfork e
+
+fn usage {+ >[2=1] echo $0 name service [proto]
+ exit usage
+}
+
+if(test $#* -lt 1)
+ usage
+name=$1
+service=$2
+if(~ $#service 0)
+ service='ssh'
+proto=$3
+if(~ $#proto 0)
+ proto='tcp'
+
+rr=`{echo _$service._$proto.$name srv | ndb/dnsquery >[2]/dev/null}+if(echo $rr | grep -s '^!dns:')
+ exit NXDOMAIN
+echo $rr |
+ awk '{printf("%s!%s!%s\n", ENVIRON["proto"], $6, $5)}'--- /dev/null
+++ b/bin/stash
@@ -1,0 +1,10 @@
+#!/bin/rc
+rfork e
+fn usage {+ >[2=1] echo $0
+ exit usage
+}
+
+cat >/tmp/stash.in
+cp /dev/text /tmp/stash.text
+cat /tmp/stash.in /tmp/stash.text >/dev/text
--- /dev/null
+++ b/bin/struct
@@ -1,0 +1,32 @@
+#!/bin/rc
+rfork en
+fn usage {>[1=2] echo 'usage:' $usage && exit 'usage'}+usage='struct [-s] [regex] [files]'
+
+regex=()
+files=()
+search='.'
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case -s
+ search='/sys/include'
+ case *
+ usage
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+
+regex=$1
+if(~ $#regex 0)
+ regex='[a-zA-Z_][a-zA-Z_0-9]*'
+if(test $#* -gt 1)
+ files=$*(2-)
+if not
+ files=`{walk -f $search | grep '\.[ch]$'}+
+echo 'X ,x/^struct([^}][^;]*\n*)+};\n/ g/^struct[ ]+'$regex'/ {+ !echo $%:$%l
+ p
+}' | sam -d $files >[2]/dev/null
--- /dev/null
+++ b/bin/struct.old
@@ -1,0 +1,81 @@
+#!/bin/rc
+# struct - find C struct definitions
+rfork e
+
+fn usage {+ >[2=1] echo struct [-pr] [pattern] [path ...]
+ exit usage
+}
+
+plumb=0
+recursive=0
+tag='%'
+include=(. /sys/include /$cputype/include)
+while(! ~ $#* 0 && ~ $1 -*){+ switch($1){+ case -p
+ plumb=1
+ case -r
+ recursive=1
+ case *
+ usage
+ }
+ shift
+}
+if(! ~ $#* 0){+ tag=$1
+ shift
+}
+if(! ~ $#* 0)
+ include=$*
+
+wf=(-f)
+if(~ $recursive 0)
+ wf=($wf -n1)
+files=`{walk $wf $include | grep '\.[ch]$'}+if(~ $#files 0)
+ exit 'no files'
+
+awk '
+BEGIN {+ plumb = ENVIRON["plumb"]
+ tag = ENVIRON["tag"]
+ if(match(tag, /%/))
+ gsub(/%/, "[a-zA-Z0-9_]+", tag)
+ tag = "[ ]" tag "[ {]?"+}
+/^[ ]*(typedef|struct|union|enum)[ ]+(typedef|struct|union|enum)?[ ]*([a-zA-Z_][a-zA-Z0-9_]*)?[ ]*{/ {+ loc = FILENAME ":" FNR
+ if(match($0, "[ ]*}[ ]*;[ ]*$") && match($0, tag)){+ if(plumb)
+ system("plumb -d edit " loc)+ else
+ printf("%s\n%s\n", loc, $0)+ next
+ }
+ collect = 1
+ found = 0
+ if(match($0, tag))
+ found = 1
+ if(found && plumb){+ system("plumb -d edit " loc)+ next
+ }
+}
+collect { ln[i++] = $0 }+collect && /^}/{+ if(found || match($0, tag)){+ print loc
+ for(j = 0; j < length(ln); j++)
+ print ln[j]
+ }
+ collect = 0
+ found = 0
+ i = 0
+ delete ln
+}
+END{+ if(found == 0)
+ exit "not found"
+}
+' $files
--- /dev/null
+++ b/bin/sz
@@ -1,0 +1,16 @@
+#!/bin/rc
+# sz -- convert computer units to bytes
+fn usage {>[1=2] echo 'usage:' $usage && exit 'usage'}+usage='sz x'
+
+{+ echo -n $1 | tr -d 'a-zA-Z'
+ echo -n '*'
+ switch($1){+ case *[kK]; echo '1024'
+ case *[mM]; echo '1024*1024'
+ case *[gG]; echo '1024*1024*1024'
+ case *[tT]; echo '1024*1024*1024*1024'
+ case *; echo '1'
+ }
+} | bc
--- /dev/null
+++ b/bin/thes
@@ -1,0 +1,7 @@
+#!/bin/rc
+url=https://www.merriam-webster.com/thesaurus
+word=`{echo $"* | sed 's/[ ]/\+/g'}+if(~ $#word 0)
+ exit
+hget $url/$word | htmlfmt | ssam '0,/^Thesaurus/+ d
+/^Learn More/-3,$ d'
--- /dev/null
+++ b/bin/trim
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec sed 's,[ ]+$,,g; s,^[ ]+,,g'
--- /dev/null
+++ b/bin/tty
@@ -1,0 +1,3 @@
+#!/bin/rc
+rfork e
+window vt -c ssh $*
--- /dev/null
+++ b/bin/var
@@ -1,0 +1,16 @@
+#!/bin/rc
+# var - find C variable declarations
+# var [pattern]
+rfork e
+
+ident='([a-zA-Z_][a-zA-Z_0-9]*)'
+var=$1
+var=`{echo $var | sed 's,%,'$ident'?,g'}+if(~ $#var 0)
+ var=$ident
+cat >/env/decl <<.
+[ ]*$ident([\* ]+$ident[, ]*)*([\* ]+$var[, ]*)+([\* ]+$ident[, ]*)*(;|=[^=]*)$
+.
+falsematch='(return|goto|typedef)[ ]+';
+srcs=`{walk -f | grep '\.[chy]$'}+grep -n -e `''{cat /env/decl} $srcs /dev/null | grep -v $falsematch | sed 's,[ ]+, ,g'--- /dev/null
+++ b/bin/vm
@@ -1,0 +1,24 @@
+#!/bin/rc -e
+rfork en
+fn usage {>[2=1] echo 'usage:' $usage && exit 'usage'}+usage='vm name'
+
+fn alp {+ name='alp'
+ root=$home/vmx/$name
+ mem=(-M 1G)
+ net=(-n ether0)
+ disk=(-d /dev/sdE0/disk0)
+ video=(-v vesa:640x480)
+ initrd=(-m initramfs-virt)
+ kernel=(vmlinuz-virt 'root=/dev/vda3' 'rootfstype=ext4')
+ cd $root
+ exec vmx $mem $disk $net $video $initrd $kernel
+}
+
+if(~ $#* 0)
+ usage
+select=$1; shift
+echo scrollon >/dev/wctl
+label $select
+$select
--- /dev/null
+++ b/bin/vmxcons
@@ -1,0 +1,10 @@
+#!/bin/rc
+name=$1
+if(~ $#name 0)
+ name='vmx'
+bind '#|' /n/p
+<>[3]/n/p/data1 {+ rm -f /srv/$name
+ echo 3 >/srv/$name.cons
+ vt con /n/p/data
+}
--- /dev/null
+++ b/bin/vmxkill
@@ -1,0 +1,6 @@
+#!/bin/rc
+for(x in (0 1 2 3 4)){+ f='#X/'^$x^'/ctl'
+ if(test -e $f)
+ echo 'quit' > $f
+}
--- /dev/null
+++ b/bin/vol
@@ -1,0 +1,28 @@
+#!/bin/rc -e
+rfork e
+fn usage {>[1=2] echo 'usage:' $usage && exit 'usage'}+usage='vol [-+] | [+-]vol | vol'
+
+fn expr {+ switch($2){+ case [-+][0-9]*
+ echo $1 $2 | bc
+ case - +
+ echo $1 $2 5 | bc
+ case *
+ echo $2
+ }
+}
+
+if(~ $#* 0)
+ usage
+
+vol=`{awk '/master/ {print $2, $3}' </dev/volume}+switch($#*){+case 1
+ vol=(`{expr $vol(1) $1})+case 2
+ vol=(`{expr $vol(1) $1} `{expr $vol(2) $2})+}
+echo master $vol
+echo master $vol >/dev/volume
--- /dev/null
+++ b/bin/w
@@ -1,0 +1,193 @@
+#!/bin/rc
+
+rfork
+
+fn usage {+ echo 'w find [regex ...]'
+ echo 'w [-t regex] cmd ...'
+ echo 'Where cmd is one or more of the following:'
+ echo ' -c wctl'
+ echo ' hide|show'
+ echo ' bottom'
+ echo ' left|Left|center|right|Right'
+ echo ' up|Up|down|Down'
+ echo ' height|width [factor]'
+ echo ' stack [offset]'
+ echo ' tile'
+ exit usage
+}
+
+fn isnum {+ echo $1 | grep -s '^[0-9\.]+$'
+}
+
+fn append {+ echo $* >>/env/wctlcmd
+}
+
+fn wfind {+ for(w in /dev/wsys/*)
+ grep -s $1 $w/label && echo $w | sed 's~.*/~~'
+}
+
+fn wwidth {+ wf=$1
+ dx=`{echo '('$riow'-'$borderoff')*'$wf | bc | sed 's~\..*~~'}+ append 'resize -dx '$dx
+}
+
+fn wheight {+ hf=$1
+ dy=`{echo '('$rioh'-'$borderoff')*'$hf | bc | sed 's~\..*~~'}+ append 'resize -dy '$dy
+}
+
+fn wmove {+ where=$1
+ win=`{read -c 48 /dev/wsys/$wid/wctl >[2]/dev/null}+ dx=`{echo $win(3) - $win(1) | bc}+ dy=`{echo $win(4) - $win(2) | bc}+ switch($where){+ case down ; append move -miny +$dy
+ case up ; append move -miny -$dy
+ case left ; append move -minx -$dx
+ case right ; append move -minx +$dx
+ case Left centerx Right
+ switch($where){+ case Left ; x=0
+ case centerx ; x=`{echo $riow / 2 - $dx / 2 | bc}+ case Right ; x=$riow
+ }
+ append move -minx $x
+ case Down centery Up
+ switch($where){+ case Down ; y=$rioh
+ case centery ; y=`{echo $rioh / 2 - $dy / 2 | bc}+ case Up ; y=0
+ }
+ append move -miny $y
+ }
+}
+
+fn wstack {+ off=$1
+ dirx=+
+ diry=+
+ if(test $bx -gt `{echo $riow / 2 - $off'*'$#wids | bc})+ dirx=-
+ if(test $by -gt `{echo $rioh / 2 - $off'*'$#wids | bc})+ diry=-
+ append move -minx $bx -miny $by
+ append move -minx $dirx$stackoff -miny $diry$stackoff
+ stackoff=`{echo $off + $stackoff | bc}+}
+
+fn wtile {+ @{+ if(~ $didtile true)
+ exit
+ tf=0.`{echo 1000 / $#wids | bc}+ for(i in `{seq 1 $#wids}){+ for(n in `{seq 2 $i})+ d=($d down)
+ wids=$wids($i) dow h $tf U $d
+ d=()
+ }
+ }
+ didtile=true
+}
+
+fn parse {+ append unhide
+ append current
+ for(arg){+ switch($1){+ case -c ; append $2; shift
+ case width w
+ if(isnum $2){wwidth $2; shift}+ if not {+ x=`{stringsize -n 82}+ x=$x(1)
+ wwidth `{echo $x' / '$riow | hoc}+ }
+ case height h
+ if(isnum $2){wheight $2; shift}+ if not {+ y=`{stringsize}+ y=$y(2)
+ wheight `{echo '(23*'$y') / '$rioh | hoc}+ }
+ case right r ; wmove right
+ case Right R ; wmove Right
+ case left l ; wmove left
+ case Left L ; wmove Left
+ case up u ; wmove up
+ case Up U ; wmove Up
+ case down d ; wmove down
+ case Down D ; wmove Down
+ case centerx cx ; wmove centerx
+ case centery cy ; wmove centery
+ case center c ; wmove centery; wmove centerx
+ case hide hi ; append hide; return=false
+ case show s ; append top
+ case delete del ; append delete; return=false
+ case bottom b ; append bottom; return=false
+ case stack
+ if(isnum $2){wstack $2; shift}+ if not {wstack 15}+ case tile ; wtile
+ case find f
+ if(~ $#* 2) {wfind $2; shift}+ if not {wfind '.*'}+ }
+ shift
+ }
+}
+
+fn dow {+ for(wid in $wids){+ parse $*
+ read -m /env/wctlcmd >>/dev/wsys/$wid/wctl
+ >/env/wctlcmd
+ }
+ if(~ $return true)
+ echo current >>/dev/wsys/$bwid/wctl
+}
+
+>/env/wctlcmd
+wid=()
+wids=()
+border=0
+borderoff=0
+stackoff=0
+return=true
+didstack=false
+didtile=false
+scr=/dev/screen
+if(test -e /mnt/orio/window){ # we're in subrio+ scr=/mnt/orio/window # refers to the subrio window
+ border=2
+ borderoff=4
+}
+rioscr=`{read -c 59 $scr}+riox=$rioscr(2)
+rioy=$rioscr(3)
+riow=`{echo $rioscr(4) - $rioscr(2) | bc}+rioh=`{echo $rioscr(5) - $rioscr(3) | bc}+bwid=`{cat /dev/winid}+bwin=`{read -c 48 /dev/wctl >[2]/dev/null}+bx=`{echo $bwin(1) - $riox - $border | bc}+by=`{echo $bwin(2) - $rioy - $border | bc}+wids=`{cat /dev/winid}+
+if(~ $#* 0)
+ dow w h 1
+while(~ $1 -*){+ switch($1){+ case -t
+ wids=`{wfind $2}+ shift
+ }
+}
+dow $*
+exit 0
--- /dev/null
+++ b/bin/web
@@ -1,0 +1,57 @@
+#!/bin/rc
+rfork e
+
+url='http://'
+query=()
+browser=plumb
+
+fn usage {+ echo 'usage: web [option] text...' >[1=2]
+ echo ' -g google'
+ echo ' -gi google image'
+ echo ' -d duckduckgo'
+ echo ' -di duckduckgo image'
+ echo ' -w wikipedia'
+ echo ' -t thesaurus'
+ echo ' -D dictionary'
+ echo ' -b libgen.io'
+ echo ' -h display this message'
+ echo ' -B browser'
+ exit 'usage'
+}
+
+if(~ $#* 0)
+ usage
+
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case -h
+ usage; exit
+ case -B
+ browser=$2
+ shift
+ case -g
+ url='http://google.com/search?q='
+ case -gi
+ url='http://google.com/images?q='
+ case -d
+ url='http://duckduckgo.com/lite/?q='
+ case -di
+ url='http://duckduckgo.com/html/?q=!bi+'
+ case -w
+ url='http://en.m.wikipedia.org/w/index.php?search='
+ case -hw
+ url='http://hr.m.wikipedia.org/w/index.php?search='
+ case -b
+ url='http://libgen.me/search.php?req='
+ case -t
+ url='https://www.merriam-webster.com/thesaurus/'
+ case -D
+ url='https://www.merriam-webster.com/dictionary/'
+ case -m
+ url='https://marc.info/?l='
+ }
+ shift
+}
+query=`{echo $"* | sed 's:[ ]:\+:g'}+$browser $url^$"query
--- /dev/null
+++ b/bin/wiki
@@ -1,0 +1,5 @@
+#!/bin/rc
+title=`{echo $* | sed 's: :_:g'}+mkdir -p /tmp/wiki
+hget 'http://en.wikipedia.org/api/rest_v1/page/html/'$title >/tmp/wiki/$title
+echo plumb 'file:///tmp/wiki/'$title
--- /dev/null
+++ b/bin/wrap
@@ -1,0 +1,24 @@
+#!/bin/rc
+rfork e
+fn usage {>[1=2] echo 'usage:' $usage && exit 'usage'}+usage='wrap start [end]'
+
+while(~ $1 -* && ! ~ $1 --){+ switch($1){+ case *
+ usage
+ }
+ shift
+}
+if(~ $1 --)
+ shift
+if(~ $#* 0)
+ usage
+
+s0 = $1
+s1 = $2
+if(~ $#* 1)
+ s1 = $s0
+echo -n $s0
+cat
+echo -n $s1
--- /dev/null
+++ b/bin/wtr
@@ -1,0 +1,4 @@
+#!/bin/rc
+if(~ $#1 0)
+ loc=varazdin
+hget http://wttr.in/~$loc.png | page -w
--- /dev/null
+++ b/bin/y
@@ -1,0 +1,6 @@
+#!/bin/rc
+# yank [register]
+where=/dev/snarf
+if(! ~ $#* 0)
+ where=/env/$1
+echo '>cat >'$where
--- /dev/null
+++ b/bin/z
@@ -1,0 +1,2 @@
+#!/bin/rc
+x/run $*
--
⑨