ref: 2959e1ede0ebc6fdffd7b8660f43c2ce14c9696f
parent: e463eb40363ff4c68b1d903f4e0cdd0ac1c5977f
author: Taru Karttunen <[email protected]>
date: Wed Mar 30 13:14:36 EDT 2011
Import sources from 2011-03-30 iso image - rc
--- /dev/null
+++ b/rc/bin/0a
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec va -L $*
--- /dev/null
+++ b/rc/bin/0c
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec vc -l $*
--- /dev/null
+++ b/rc/bin/0l
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec vl -L $*
--- /dev/null
+++ b/rc/bin/9fs
@@ -1,0 +1,55 @@
+#!/bin/rc
+# 9fs filesystem [mountpoint] - srv & mount filesystem, usually from plan 9
+
+rfork e
+switch($1){
+case ''
+ echo usage: 9fs service '[mountpoint]' >[1=2]
+ exit usage
+case kfs
+ if(! test -f /srv/kfs)
+ disk/kfs
+ mount -c /srv/kfs /n/kfs
+case dump
+ mount /srv/boot /n/dump dump >[2]/dev/null ||
+ mount /srv/boot /n/dump main/archive ||
+ mount /srv/boot /n/dump dump # again to print error
+case snap
+ mount /srv/boot /n/snap main/snapshot
+case other
+ mount -C /srv/boot /n/other other
+case juke # ye olde file server
+ srv -q il!jukefs && mount /srv/il!jukefs /n/juke
+case sources
+ srv -nq tcp!sources.cs.bell-labs.com sources /n/sources
+case sourcesdump
+ 9fs sources
+ mount -n /srv/sources /n/sourcesdump main/archive
+case sourcessnap
+ 9fs sources
+ mount -n /srv/sources /n/sourcessnap main/snapshot
+# arbitrary venti archives
+case vac:*
+ vacfs <{echo $1}
+case *.vac
+ if (test -e $1)
+ score=$1
+ if not if (! ~ $1 /* && test -e $home/lib/vac/$1)
+ score=$home/lib/vac/$1
+ if not if (! ~ $1 /* && test -e /lib/vac/$1)
+ score=/lib/vac/$1
+ if not {
+ echo $0: $1: no such score file >[1=2]
+ exit 'no score file'
+ }
+ vacfs -m /n/`{basename $1 .vac} `{cat $score}
+case wiki
+ srv -m 'net!plan9.bell-labs.com!wiki' wiki /mnt/wiki
+case *
+ switch($#*){
+ case 1
+ srv -m $1
+ case *
+ srv -m $1 $1 $2
+ }
+}
--- /dev/null
+++ b/rc/bin/B
@@ -1,0 +1,40 @@
+#!/bin/rc
+
+files=()
+dest=()
+
+if(~ $#* 0){
+ echo usage: B file ... >[1=2]
+ exit usage
+}
+
+for(i)
+ switch($i){
+ case /*
+ files = ( $files $i )
+ case *
+ files = ( $files `{cleanname `{pwd}^/$i} )
+ }
+
+
+if(test -f /mnt/plumb/edit || test -f /mnt/term/mnt/plumb/edit){
+ plumb -s B -d edit $files
+ exit
+}
+
+# using sam srv file
+
+if(test -f /mnt/term/srv/sam.$user) dest = /mnt/term/srv/sam.$user
+if not if(test -f /srv/sam.$user) dest = /srv/sam.$user
+if not {
+ echo B: can''''t find sam server file >[1=2]
+ exit open
+}
+
+switch($files){
+case *:*
+ for(i in $files)
+ echo $i | sed 's/^/B /;s/:([0-9]+)$/\n\1/g' >> $dest
+case *
+ echo B $files >> $dest
+}
--- /dev/null
+++ b/rc/bin/C
@@ -1,0 +1,66 @@
+#!/bin/rc
+# C system - connect to system's console
+rfork en
+oflag=()
+opt=-r
+while(~ $1 -*)
+ switch($1){
+ case -r
+ shift
+ opt=''
+ case -O -o
+ oflag=-O
+ shift
+ case *
+ opt=-r
+ shift
+ }
+
+switch($1){
+case ella
+ exec C office0
+ exit
+case erika
+ exec C office1
+ exit
+case *
+ # look for server in /lib/ndb
+ server=`{ndb/query sys $1 console}
+ switch($server){
+ case ''
+ echo C: unknown console server for $1
+ exit 1
+ }
+}
+
+# can't cpu to old servers any more
+switch($server){
+case dinar bones
+ ssh $server C $1
+ exit 0
+}
+
+if(! test -e /mnt/consoles/$1){
+ switch($sysname){
+ case $server
+ mount /srv/consoles /mnt/consoles
+ case *
+ import $oflag $server /mnt/consoles
+ }
+}
+
+if(! test -e /mnt/consoles/$1 && test -e /srv/consoles)
+ mount /srv/consoles /mnt/consoles
+
+if(! test -e /mnt/consoles/$1){
+ echo console not found
+ exit 'console not found'
+}
+
+if (test -w /dev/label) {
+ olab=`{cat /dev/label}
+ label $1
+}
+con -l $opt /mnt/consoles/$1
+if (test -w /dev/label)
+ label $olab
--- /dev/null
+++ b/rc/bin/D003753
@@ -1,0 +1,11 @@
+#!/bin/rc
+rfork e
+flop=/dev/fd0disk
+if(! test -r $flop)
+ flop='#f'/fd0disk
+if(! test -f /srv/dos)
+ dossrv >/dev/null </dev/null >[2]/dev/null
+unmount /n/a:>[2]/dev/null
+mount -c /srv/dos /n/a: $flop
+unmount /n/a >[2]/dev/null
+mount -c /srv/dos /n/a $flop
--- /dev/null
+++ b/rc/bin/D003754
@@ -1,0 +1,9 @@
+#!/bin/rc
+
+rfork e
+
+if(test -f /dev/sd*/dos*){
+ dosmnt 1 /n/c:
+ dosmnt 1 /n/c
+ exit
+}
--- /dev/null
+++ b/rc/bin/F000050
@@ -1,0 +1,68 @@
+#!/bin/rc
+# usbfat: [disk [mtpt]] - mount a USB disk's MS FAT file system,
+# which might be the only thing on the disk, or might be
+# a partition within the disk.
+rfork e
+disk = ()
+mtpt = /n/usb
+
+test -e /dev/usb || bind -a '#u' /dev || {
+ echo no '#u/usb' >[1=2]
+ exit nousb
+}
+test -e /dev/usbdctl || mount -a /srv/usb /dev || {
+ echo cannot mount /srv/usb >[1=2]
+ exit nousbd
+}
+
+disks=()
+mtpt=()
+switch ($#*) {
+case 0
+ ;
+case 1
+ disks = $1
+case 2
+ disks = $1
+ mtpt = $2
+case *
+ echo usage: $0 ' [disk [mtpt]]' >[1=2]
+ exit usage
+}
+
+if(~ `{ls /n/usb >[2]/dev/null | wc -l} 0)
+ mount /srv/usb /n/usb >[2]/dev/null
+if (~ $#disks 0){
+ disks = /dev/sdU*/data
+ if(! test -e $disks(1)){
+ echo no usb disks >[1=2]
+ exit nodisk
+ }
+ disks = (/dev/sdU*/9fat /dev/sdXX/9fat /dev/sdU*/data /dev/sdXX/data)
+}
+for(d in $disks){
+ if(! ~ $done yes) {
+ if(~ $d sdU*.[0-9]* sdXX*)
+ d=/dev/$d/data
+ if(test -e $d){
+ name=`{echo $d | sed 's/.*(sd(XX|U[0-9]+\.[0-9]+)).*/\1/'}
+ if(~ $#mtpt 0)
+ mnt=/n/$name
+ if not
+ mnt=$mtpt
+ # don't mount it if it seems to be already mounted.
+ # if(! test -e $mnt/* && grep -s geometry /dev/$name/ctl)
+ {
+ blk = `{disk/fdisk -p $d |
+ awk '/^part dos / {print $3}'}
+ if (! ~ $#blk 0 && ~ $blk [0-9]*)
+ d=$d:$blk
+ if (mount -c <{dossrv -sf $d >[2]/dev/null} $mnt) {
+ echo $mnt
+ done = yes
+ }
+ }
+ }
+ }
+}
+exit ''
--- /dev/null
+++ b/rc/bin/F003758
@@ -1,0 +1,18 @@
+#!/bin/rc
+
+rfork e
+part=`{ls /dev/fs/9fat /dev/sd*/9fat >[2]/dev/null}
+if(~ $#part 0) {
+ echo 'no 9fat partition found' >[1=2]
+ exit no.9fat
+}
+
+part=$part(1)
+
+if(! test -f /srv/dos)
+ dossrv >/dev/null </dev/null >[2]/dev/null
+
+unmount /n/9fat >/dev/null >[2]/dev/null
+mount -c /srv/dos /n/9fat $part
+unmount /n/9 >/dev/null >[2]/dev/null
+mount -c /srv/dos /n/9 $part
--- /dev/null
+++ b/rc/bin/F003763
@@ -1,0 +1,7 @@
+#!/bin/rc
+if(! test -f /srv/dos)
+ dossrv >/dev/null </dev/null >[2]/dev/null
+unmount /n/b:>[2]/dev/null
+mount -c /srv/dos /n/b: /dev/fd1disk
+unmount /n/b >[2]/dev/null
+mount -c /srv/dos /n/b /dev/fd1disk
--- /dev/null
+++ b/rc/bin/Kill
@@ -1,0 +1,4 @@
+#!/bin/rc
+for(i){
+ ps | sed -n '/ '^$i^'$/s%^[^ ]* *([^ ]*).*%chmod 666 /proc/\1/ctl;echo kill > /proc/\1/ctl%p'
+}
--- /dev/null
+++ b/rc/bin/addaoe
@@ -1,0 +1,8 @@
+#!/bin/rc
+# addaoe let unit - add an AoE logical unit as sd$let
+if (! ~ $#* 2 || ! ~ $1 ? || ! ~ $2 *.*) {
+ echo usage: $0 letter aoe-lun >[1=2]
+ exit usage
+}
+if (test -e /dev/aoe/$2 && ! test -e /dev/sd^$1^0)
+ echo config switch on spec $1 type aoe//dev/aoe/$2 >/dev/sdctl
--- /dev/null
+++ b/rc/bin/addpsfonts
@@ -1,0 +1,5 @@
+#!/bin/rc
+# addpsfonts [file]... - add postscript fonts named in %%DocumentFonts comments
+# of postscript input
+echo %!PS-Adobe-2.0
+exec aux/download -f -mfontmap -plw+ -r/sys/lib/postscript/font/lw+ $*
--- /dev/null
+++ b/rc/bin/ap
@@ -1,0 +1,36 @@
+#!/bin/rc
+#
+# get AP news headline list or the given story
+#
+
+wire='http://www.newsday.com/news/nationworld/wire'
+if ( ~ $#* 0 )
+ hget $wire | #tee /tmp/ap.$pid |
+ sed -n '/<h1>AP Top News/,/AP News Wire/p' |
+ htmlfmt -a -w 100 |
+ sed -n '
+ /^• / {
+ N
+ s/^• / /g
+ s/\n/ /g
+ s/\[\/news\/nationworld\/wire\//|/
+ s/sns-ap-//
+ s/\.story.*$//
+ p
+ }' |
+ awk -F '|' '
+ {
+ s = "";
+ for (i = 1; i < NF; i++)
+ s = s " " $i;
+ printf("ap %-40s # %s\n", $NF, s);
+ }'
+
+if not
+ hget $wire/sns-ap-^$1^.story |
+ htmlfmt |
+ sed '
+ 1,/^AP Top News$/d
+ /^\* __$/,$d
+ /^Subscribe to Newsday home delivery/,$d
+ '
--- /dev/null
+++ b/rc/bin/ape/ar89
@@ -1,0 +1,15 @@
+#!/bin/rc
+
+flagfmt='c,d,p,r,t,u,v,x'
+args='archive [files ...]'
+
+if(! ifs=() eval `{aux/getflags $*} || ~ $#* 0) {
+ aux/usage
+ exit usage
+}
+
+key=''
+for(i in c d p r t x u v)
+ if(f=flag$i ~ $#$f 1)
+ key=$key$i
+exec /$cputype/bin/ar $key $*
--- /dev/null
+++ b/rc/bin/ape/c89
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec /$cputype/bin/ape/cc $*
--- /dev/null
+++ b/rc/bin/ape/cat
@@ -1,0 +1,18 @@
+#!/bin/rc
+
+rfork e
+
+files=()
+while(! ~ $#* 0){
+ switch($1){
+ case -
+ files=($files /fd/0)
+ case -*
+ ;
+ case *
+ files=($files $1)
+ }
+ shift
+}
+
+exec /$cputype/bin/cat $files
--- /dev/null
+++ b/rc/bin/ape/chown
@@ -1,0 +1,4 @@
+#!/bin/rc
+
+echo 'Permission denied'
+exit 1
--- /dev/null
+++ b/rc/bin/ape/dircp
@@ -1,0 +1,9 @@
+#!/bin/rc
+# dircp src dest - copy a tree with ape's tar
+switch($#*){
+case 2
+ @{cd $1 && tar cf /fd/1 .} | @{cd $2 && tar xf /fd/0}
+case *
+ echo usage: dircp from to >[1=2]
+ exit usage
+}
--- /dev/null
+++ b/rc/bin/ape/egrep
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec /rc/bin/ape/grep $*
--- /dev/null
+++ b/rc/bin/ape/false
@@ -1,0 +1,2 @@
+#!/bin/rc
+exit 1
--- /dev/null
+++ b/rc/bin/ape/fgrep
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec /rc/bin/ape/grep $*
--- /dev/null
+++ b/rc/bin/ape/grep
@@ -1,0 +1,22 @@
+#!/bin/rc
+
+rfork e
+
+opts=()
+files=()
+argv0=$0
+while(! ~ $#* 0){
+ switch($1){
+ case -[cefinsv]
+ opts=($opts $1)
+ case -q
+ opts=($opts -s)
+ case -*
+ echo $argv0 $1 not supported >[2=1]
+ exit 'not supported'
+ case *
+ files=($files $1)
+ }
+ shift
+}
+exec /$cputype/bin/grep $opts $files
--- /dev/null
+++ b/rc/bin/ape/install
@@ -1,0 +1,40 @@
+#!/bin/rc
+# Usage: install [options] srcfile dstfile
+# Usage: install srcfile dstfile owner group mode
+
+fn usage {
+ echo 'usage: install [-c|-m mode] srcfile dstfile' >[1=2]
+ exit 1
+}
+
+mode=775
+while(! ~ $#* 0){
+ switch($1){
+ case -c
+ ;
+ case -m
+ mode=$2
+ shift
+ case -*
+ usage
+ case *
+ switch($#*) {
+ case 2
+ ;
+ case 5
+ mode=$5 # backward compatibility
+ case *
+ usage
+ }
+ srcfile=$1
+ dstfile=$2
+ if (! test -f $dstfile || ! cmp -s $srcfile $dstfile) {
+ cp $srcfile $dstfile
+ chmod $mode $dstfile
+ chmod g+w $dstfile
+ }
+ exit 0
+ }
+ shift
+}
+usage
--- /dev/null
+++ b/rc/bin/ape/ld
@@ -1,0 +1,6 @@
+#!/bin/rc
+# ld for ape, to keep configure happy
+
+O=`{sed -n 's/^O=//p' /$cputype/mkfile}
+
+$O^l $*
--- /dev/null
+++ b/rc/bin/ape/ln
@@ -1,0 +1,23 @@
+#!/bin/rc
+
+argv0=$0
+force=n
+while(! ~ $#* 0 && ~ $1 -*){
+ switch($1){
+ case -f
+ force=y
+ case -s
+ ;
+ case *
+ echo 'usage: ln [-s] [-f] source destination' >[2=1]
+ exit 'usage'
+ }
+ shift
+}
+
+if(~ $force n && test -e $2){
+ echo ln: $2 destination exists >[2=1]
+ exit 'usage'
+}
+
+exec cp -gux $1 $2
--- /dev/null
+++ b/rc/bin/ape/ls
@@ -1,0 +1,59 @@
+#!/bin/rc
+
+# flags common to GNU and BSD ls
+
+# -A all except . and ..
+# -C force mc
+# -F usual
+# -H follow symlinks
+# -L follow symlinks
+# -R recursive list
+# -U unsorted (gnu)
+#
+# -a include .files
+# -c show ctime
+# -d dirs
+# -f no sorting
+# -l long
+# -p put slash after dir (-F)
+# -r reverse
+# -s sizes
+# -t time sort
+# -u utime
+# -1 single-column
+
+
+flagfmt='A,C,F,H,L,R,U,a,c,d,f,l,p,r,s,t,u,1'
+args='[file ...]'
+
+if(! ifs=() eval `{aux/getflags $*}){
+ aux/usage
+ exit usage
+}
+
+fn fixlong {
+ echo total 1000
+ /$cputype/bin/sed 's/^(.).(.........) . [0-9]+ /\1\2 1 /'
+}
+
+post=cat
+
+all=()
+# ignore -A
+if(~ $flagC 1) post=mc
+if(~ $flagF 1) all=($all -F)
+# ignore -H, -L
+# save -R for later
+if(~ $flagU 1) all=($all -n)
+# ignore -a, -c
+if(~ $flagd 1) all=($all -d)
+if(~ $flagf 1) all=($all -n)
+if(~ $flagl 1) { all=($all -l); post=fixlong }
+if(~ $flagp 1) all=($all -F)
+if(~ $flagr 1) all=($all -r)
+if(~ $flags 1) all=($all -s)
+if(~ $flagt 1) all=($all -t)
+if(~ $flagu 1) all=($all -u)
+# ignore -1
+
+/$cputype/bin/ls $all $* | $post
--- /dev/null
+++ b/rc/bin/ape/printf
@@ -1,0 +1,4 @@
+#!/bin/rc
+
+# Here only for autoconf and friends.
+echo -n $1
--- /dev/null
+++ b/rc/bin/ape/psh
@@ -1,0 +1,10 @@
+#!/bin/rc
+# set up a shell running in an approximate POSIX 1003.2 environment
+rfork en
+fn sigterm{}
+HOME=$home
+bind -b /rc/bin/ape /bin
+bind -b /$cputype/bin/ape /bin
+if(test -d /$cputype/bin/pub)
+ bind -a /$cputype/bin/pub /bin
+/bin/sh $*
--- /dev/null
+++ b/rc/bin/ape/ranlib
@@ -1,0 +1,3 @@
+#!/bin/rc
+
+exit 0
--- /dev/null
+++ b/rc/bin/ape/rmdir
@@ -1,0 +1,2 @@
+#!/bin/rc
+rm $*
--- /dev/null
+++ b/rc/bin/ape/true
@@ -1,0 +1,2 @@
+#!/bin/rc
+exit 0
--- /dev/null
+++ b/rc/bin/ape/umask
@@ -1,0 +1,2 @@
+#!/bin/rc
+echo no umask in Plan 9
--- /dev/null
+++ b/rc/bin/ape/yacc
@@ -1,0 +1,16 @@
+#!/bin/rc
+
+flagfmt='d,l,t,v,b stem'
+args='grammar'
+
+if(! ifs=() eval `{aux/getflags $*} || ! ~ $#* 1){
+ aux/usage
+ exit usage
+}
+
+y=-S
+if (~ $#flagb 1) y=($y -s $flagb)
+if (~ $#flagd 1) y=($y -d)
+if (~ $#flagt 1) y=($y -D2)
+if (~ $#flagv 1) y=($y -v)
+exec /$cputype/bin/yacc $y $*
--- /dev/null
+++ b/rc/bin/broke
@@ -1,0 +1,8 @@
+#!/bin/rc
+U=`{cat /dev/user}
+if(~ $#* 1){
+ U=$1
+}
+ps | sed -n '/^'$U' .* Broken/s%[^ ]* *%~>/proc/%
+s% *.* (.*)%/ctl # \1%
+s%~%echo kill%p'
--- /dev/null
+++ b/rc/bin/bundle
@@ -1,0 +1,8 @@
+#!/bin/rc
+echo '# To unbundle, run this file'
+for(i in $*){
+ echo 'echo '$i
+ echo 'sed ''s/.//'' >'$i' <<''//GO.SYSIN DD '$i''''
+ sed 's/^/-/' $i
+ echo '//GO.SYSIN DD '$i
+}
--- /dev/null
+++ b/rc/bin/cpurc
@@ -1,0 +1,77 @@
+#!/bin/rc
+# cpu server start up
+date > /env/boottime
+
+# mount points
+mntgen -s slashn && chmod 666 /srv/slashn
+
+# name translation, cs sets /dev/sysname
+ndb/cs
+sysname=`{cat /dev/sysname}
+
+# parallelism for mk
+NPROC = `{wc -l </dev/sysstat}
+
+# site-specific startup
+if(test -e /rc/bin/cpurc.local)
+ . /rc/bin/cpurc.local
+
+if (~ $#sysname 0 || ~ $sysname '') {
+ sysname = helix # default
+ echo -n $sysname >/dev/sysname
+}
+prompt=($sysname^'# ' ' ')
+
+# cpu-specific startup
+if(test -e /cfg/$sysname/cpurc)
+ . /cfg/$sysname/cpurc
+
+# start up internet if we don't already have an address
+if(! grep u /net/ipselftab | grep -sv 127.0.0.1)
+ ip/ipconfig
+if(! grep -s 127.0.0.1 /net/ipselftab)
+ ip/ipconfig loopback /dev/null 127.1
+
+# if we're not a server, start a dns resolver
+if(! test -e /srv/dns)
+ ndb/dns -r
+
+# If you are on an auth server, start these before listening:
+#
+# auth/keyfs -wp -m /mnt/keys /adm/keys >/dev/null >[2=1]
+# auth/cron >>/sys/log/cron >[2=1] &
+#
+# also rename some files:
+#
+# if(! test -e /rc/bin/service.auth/tcp567){
+# mv /rc/bin/service.auth/authsrv.il566 /rc/bin/service.auth/il566
+# mv /rc/bin/service.auth/authsrv.tcp567 /rc/bin/service.auth/tcp567
+# mv /rc/bin/service/il566 /rc/bin/service/_il566
+# mv /rc/bin/service/tcp567 /rc/bin/service/_tcp567
+# }
+
+# start listeners if it hasn't already been done (dicey check)
+if(! netstat -n | grep -s 'tcp.*Listen.* (7|9|21|22|23|25|110|113|565|993|17007|17009|17010) .*')
+ aux/listen -q tcp
+# we don't use IL, maybe you do
+if(! netstat -n | grep -v 17008 | grep -s il.*Listen)
+ aux/listen -q il
+
+if(! ps|grep -s timesync) {
+ aux/timesync -n pool.ntp.org
+ if (test -e '#r/rtc') @ {
+ sleep 10 # let timesync correct the time
+ awk '{print $1}' /dev/time >'#r/rtc' # fix hw clock
+ } &
+}
+
+# cpu-specific late startup
+if(test -e /cfg/$sysname/cpustart)
+ . /cfg/$sysname/cpustart
+
+# mode of /proc/*/ctl is inherited across rfork, and sets modes on
+# other /proc files, such as note, so let listen be killed.
+dontkill '^(ipconfig|factotum|mntgen|venti|fossil|cs|dns|reboot)$'
+
+# echo `{date} $sysname >>/sys/log/boot
+exit ''
--- /dev/null
+++ b/rc/bin/cpurc.local
@@ -1,0 +1,11 @@
+#!/bin/rc
+# local cpu startup
+
+# used only by upas, as default return domain appended to all unqualified
+# return addresses, even local ones
+site=EXAMPLE
+# replace FILESERVER with the name of your file server
+# here we start with kfs, your local disk file system
+fileserver=kfs
+# replace FACEDOM with the local domain to be used in the faces database
+facedom=FACEDOM
--- /dev/null
+++ b/rc/bin/delkey
@@ -1,0 +1,52 @@
+#!/bin/rc
+
+rfork e
+
+ctl = /mnt/factotum/ctl
+if(test -r /mnt/term/mnt/factotum/ctl)
+ ctl = /mnt/term/mnt/factotum/ctl
+
+fn forceit {
+ switch($force){
+ case no
+ echo -n $* '? [y/n]' > /dev/cons
+ ok = `{read}
+ switch($ok){
+ case y* Y*
+ echo yes
+ case q* Q*
+ exit ''
+ case *
+ echo no
+ }
+ case *
+ echo yes
+ }
+}
+
+fn deleteit {
+ key = `{echo $* | sed 's/ ![0-9a-zA-Z_]+\??/ /g' | sed 's/ +$//'}
+ if(~ `{forceit del$key} yes)
+ if(! echo del$key > $ctl)
+ exit bad
+}
+
+force = no
+
+if(~ $1 '-f'){
+ force = yes
+ shift
+}
+
+ifs='
+'
+
+if(~ $#* 0){
+ for(i in `{cat $ctl})
+ deleteit $i
+ exit ''
+}
+
+for(i in `{grep $"* $ctl})
+ deleteit $i
+exit ''
--- /dev/null
+++ b/rc/bin/diffy
@@ -1,0 +1,14 @@
+#!/bin/rc
+# diffy [diff-opts] file... - diff file against yesterday's version(s)
+rfork e
+diffopts=()
+while(! ~ $#* 0 && ~ $1 -* && ! ~ $1 --){
+ diffopts=($diffopts $1)
+ shift
+}
+if(~ $1 --)
+ shift
+if(! ~ $#* 1)
+ diffopts=($diffopts -m)
+for(f)
+ diff $diffopts `{yesterday $f} $f
--- /dev/null
+++ b/rc/bin/dircp
@@ -1,0 +1,9 @@
+#!/bin/rc
+# dircp src dest - copy a tree with tar
+switch($#*){
+case 2
+ @ {builtin cd $1 && tar cif /fd/1 .} | @ {builtin cd $2 && tar xTf /fd/0}
+case *
+ echo usage: dircp from to >[1=2]
+ exit usage
+}
--- /dev/null
+++ b/rc/bin/diskparts
@@ -1,0 +1,34 @@
+#!/bin/rc
+# set up any disk partitions
+rfork e
+if (! test -e /dev/sdctl)
+ bind -b '#S' /dev
+
+# set up any /dev/sd partitions.
+# note that really big disks (e.g., aoe devices) may have no mbr
+# partition table because the mbr partition table can't cope with large
+# block numbers, so we may have to examine the data file with prep if
+# there's no plan9 file. beware that `disk/prep -p data' on a disk with
+# no plan 9 partition table will delete all extant partitions.
+for(disk in /dev/sd*) {
+ if(test -f $disk/data && test -f $disk/ctl)
+ { disk/fdisk -p $disk/data |
+ grep -v '^delpart ' >$disk/ctl } >[2]/dev/null
+ if(test -f $disk/plan9)
+ parts=($disk/plan9*)
+ if not
+ parts=($disk/data)
+ for(part in $parts)
+ if(test -f $part)
+ { disk/prep -p $part |
+ grep -v '^delpart ' >$disk/ctl } >[2]/dev/null
+}
+
+sysname=`{cat /dev/sysname}
+
+# set up any fs(3) partitions
+if (! test -e /dev/fs/ctl && test -e '#k/fs')
+ bind -b '#k' /dev
+if (~ $#sysname 1 && ! ~ $sysname '' &&
+ test -r /cfg/$sysname/fsconfig && test -w /dev/fs/ctl)
+ read -m /cfg/$sysname/fsconfig >/dev/fs/ctl
--- /dev/null
+++ b/rc/bin/dmaon
@@ -1,0 +1,7 @@
+#!/bin/rc
+# dmaon - turn on ide dma, if possible
+rfork e
+for (ctl in /dev/sd[C-H]?/ctl)
+ if (test -e $ctl && grep -s '^config .* dma ' $ctl &&
+ ! grep -s '^config (848A|.* dma 00000000 )' $ctl)
+ echo 'dma on' >$ctl
--- /dev/null
+++ b/rc/bin/doc2ps
@@ -1,0 +1,21 @@
+#!/bin/rc
+# doc2ps [file.doc] - convert ms word document to postscript
+rfork e
+fn usage {
+ echo usage: doc2ps '[file.doc]' >[1=2]
+ exit usage
+}
+switch ($#*) {
+case 0
+ file=/tmp/antiword.doc.$pid
+ fn sigexit { rm $file; exit $s }
+ cat >$file
+case 1
+ if(~ $1 -*)
+ usage
+ file=$1
+case *
+ usage
+}
+aux/antiword -i0 -p letter $file
+s=$status
--- /dev/null
+++ b/rc/bin/doc2txt
@@ -1,0 +1,31 @@
+#!/bin/rc
+
+rfork en
+
+if(! ~ $#* 0 1) {
+ echo 'Usage: doc2txt [file.doc]' >[1=2]
+ exit usage
+}
+
+switch($#*){
+case 0
+ cat >/tmp/doc2txt.$pid
+ file=/tmp/doc2txt.$pid
+case 1
+ file=$1
+}
+aux/olefs $file || {
+ echo 'doc2txt: couldn''t mount word document' >[1=2]
+ rm -f /tmp/doc2txt.$pid
+ exit word
+}
+
+if(! test -f /mnt/doc/WordDocument) {
+ echo 'doc2txt: is an msoffice doc but not a word document' >[1=2]
+ rm -f /tmp/doc2txt.$pid
+ exit worddoc
+}
+
+aux/mswordstrings /mnt/doc/WordDocument | tcs -f microsoft -t utf |fmt | uniq
+unmount /mnt/doc
+rm -f /tmp/doc2txt.$pid
--- /dev/null
+++ b/rc/bin/doctype
@@ -1,0 +1,76 @@
+#!/bin/rc
+# doctype: synthesize proper command line for troff
+
+troff=troff
+eqn=eqn
+prefer=prefer
+opt=''
+dev=''
+while(~ $1 -*){
+ switch($1){
+ case -n;
+ troff=nroff
+ eqn=neqn
+ prefer='prefer -n'
+ case -T
+ dev=$1
+ case -*
+ opt=$opt' $1'
+ }
+ shift
+}
+ifs='
+'{
+ files=`{echo $*}
+}
+grep -h '\$LIST|\|reference|Jp|^\.(EQ|TS|\[|PS|IS|GS|G1|GD|PP|BM|LP|BP|PI|cstart|begin|TH...)|^\.P$' $* |
+sort -u |
+awk '
+BEGIN { files = "'$files'" }
+/\$LIST/ { e++ }
+/^\.PP/ { ms++ }
+/^\.LP/ { ms++ }
+/^\.EQ/ { eqn++ }
+/^\.TS/ { tbl++ }
+/^\.PS/ { pic++ }
+/^\.IS/ { ideal++ }
+/^\.GS/ { tped++ }
+/^\.G1/ { grap++; pic++ }
+/^\.GD/ { dag++; pic++ }
+/^\.\[/ { refer++ }
+/\|reference/ { prefer++ }
+/^\.cstart/ { chem++; pic++ }
+/^\.begin +dformat/ { dformat++; pic++ }
+/^\.TH.../ { man++ }
+/^\.BM/ { lbits++ }
+/^\.P$/ { mm++ }
+/^\.BP/ { pictures++ }
+/^\.PI/ { pictures++ }
+/^\.ft *Jp|\\f\(Jp/ { nihongo++ }
+END {
+ x = ""
+ if (refer) {
+ if (e) x = "refer/refer -e " files " | "
+ else x = "refer/refer " files "| "
+ files = ""
+ }
+ else if (prefer) { x = "cat " files "| '$prefer'| "; files = "" }
+ if (tped) { x = x "tped " files " | "; files = "" }
+ if (dag) { x = x "dag " files " | "; files = "" }
+ if (ideal) { x = x "ideal -q " files " | "; files = "" }
+ if (grap) { x = x "grap " files " | "; files = "" }
+ if (chem) { x = x "chem " files " | "; files = "" }
+ if (dformat) { x = x "dformat " files " | "; files = "" }
+ if (pic) { x = x "pic " files " | "; files = "" }
+ if (tbl) { x = x "tbl " files " | "; files = "" }
+ if (eqn) { x = x "'$eqn' '$dev' " files " | "; files = "" }
+ x = x "'$troff' "
+ if (man) x = x "-man"
+ else if (ms) x = x "-ms"
+ else if (mm) x = x "-mm"
+ if (lbits) x = x " -mbits"
+ if (pictures) x = x " -mpictures"
+ if (nihongo) x = x " -mnihongo"
+ x = x " '$opt' '$dev' " files
+ print x
+}'
--- /dev/null
+++ b/rc/bin/dontkill
@@ -1,0 +1,10 @@
+#!/bin/rc
+# dontkill regexp - mark invoker's processes with names matching regexp
+# as not killable when the kernel runs out of memory
+if (! ~ $#* 1) {
+ echo $0 regexp >[1=2]
+ exit usage
+}
+# see /sys/src/9/port/proc.c:/^killbig
+pids=`{psu | awk '$NF ~ /'$1'/ {print $2}'}
+~ $#pids 0 || chmod -w /proc/^$pids^/ctl
--- /dev/null
+++ b/rc/bin/dosmnt
@@ -1,0 +1,18 @@
+#!/bin/rc
+
+rfork e
+if(! ~ $#* 2){
+ echo 'usage: dosmnt N mntpt' >[1=2]
+ exit usage
+}
+
+x=(`{ls /dev/sd??/dos* >[2]/dev/null |uniq})
+if(test $#x -lt $1){
+ echo 'not that many dos disks' >[1=2]
+ exit usage
+}
+
+if(! test -f /srv/dos)
+ dossrv >/dev/null </dev/null >[2]/dev/null
+
+mount -c /srv/dos $2 $x($1)
--- /dev/null
+++ b/rc/bin/dpost
@@ -1,0 +1,10 @@
+#!/bin/rc
+# dpost [-f] [file...] - convert troff output to postscript,
+# optionally include font def'ns
+# exec lp -dstdout $*
+if (! ~ $#* 0 && ~ $1 -f) {
+ shift
+ aux/tr2post $* | addpsfonts
+}
+if not
+ exec aux/tr2post $*
--- /dev/null
+++ b/rc/bin/eject
@@ -1,0 +1,9 @@
+#!/bin/rc
+switch($1){
+case 0
+ echo eject > /dev/fd0ctl
+case 1
+ echo eject > /dev/fd1ctl
+case *
+ echo eject > /dev/fd0ctl
+}
--- /dev/null
+++ b/rc/bin/fax
@@ -1,0 +1,126 @@
+#!/bin/rc
+# fax [-v] telephone-number recipient [file ...] - send files via fax
+rfork e
+view=no
+stdin=no
+
+fn usage {
+ echo 'usage: fax [-v] telephone-number recipient [file ...]' >[1=2]
+ exit usage
+}
+
+switch($1){
+case -v
+ view=yes
+ shift
+}
+
+switch ($#*) {
+case 0 1
+ usage
+case 2
+ stdin=yes
+}
+telno=`{echo $1|sed 's/[ \-]//g'}
+shift
+
+if (! ~ $telno [0-9]* +[0-9]*)
+ usage
+
+# our old phone system needed *9 to get outside; the new one just needs 9
+switch($telno){
+case ???????
+ telno='9,'^$telno
+case ??????????
+ telno='9,1'^$telno
+case 1??????????
+ telno='9,'^$telno
+case 011*
+ telno='9,'^$telno
+case +*
+ telno=`{echo $telno | sed 's/\+/9,011/'}
+}
+
+recip=$1
+shift
+
+script=/tmp/fax.$pid
+header=/tmp/faxh.$pid
+user=`{cat /dev/user}
+tmp=/tmp/fax.g3.$pid
+tmpin=/tmp/fax.in.$pid
+tmpps=/tmp/fax.ps.$pid
+tel=`{grep '\) '$user /lib/tel}
+myname=`{echo $tel | sed 's/ \(.*//'}
+if (~ $#myname 0)
+ myname=''
+ext=`{echo $tel | sed 's/.*\) [^ ]* [^ ]* ([^ ]*).*/\1/'}
+
+fn sigexit {
+ rm -f $tmp.* $script $header $header.* $tmpin $tmpps
+}
+fn sigint {
+ sigexit
+ exit interrupt
+}
+
+# gather input into a file
+switch($stdin){
+case yes
+ cat >$tmpin
+ infiles=$tmpin
+case *
+ infiles=($*)
+}
+
+# convert to g3
+g3files=()
+a=1
+for(i in $infiles){
+ switch(`{file $i}){
+ case *:*g3* *:*fax*
+ g3files=($g3files $i)
+ case *:*postscript
+ gs -dSAFER '-sDEVICE=dfaxlow' '-sOUTPUTFILE='$tmp'.'$#a'.%03d' \
+ -dNOPAUSE -dQUIET $i quit.ps
+ g3files=($g3files $tmp.$#a.*)
+ case *
+ lp -dstdout $i >$tmpps
+ gs -dSAFER '-sDEVICE=dfaxlow' '-sOUTPUTFILE='$tmp'.'$#a'.%03d' \
+ -dNOPAUSE -dQUIET $tmpps quit.ps
+ g3files=($g3files $tmp.$#a.*)
+ }
+ a=($a 1) # count by increasing list length
+}
+
+pages=`{echo $g3files|wc -w}
+
+# use delimiters that are unlikely to be supplied in arguments
+{
+ echo -n s∮FAXddd∮
+ echo -n `{date} # treat `{} output list specially
+ echo ∮
+ echo s∮FAXFFF∮$"myname^∮
+ echo s∮FAXEEE∮$"user^∮
+ echo s∮FAXVVV∮$"ext^∮
+ echo s∮FAXTTT∮$"recip^∮
+ echo s∮FAXfff∮$"telno^∮
+ echo s∮FAXPPP∮$"pages^∮
+} >>$script
+sed -f $script /sys/lib/fax/h.ps >$header
+
+gs -dSAFER '-sDEVICE=dfaxlow' '-sOUTPUTFILE='$header'.%03d' \
+ -dNOPAUSE -dQUIET $header quit.ps
+
+files=()
+for(i in $header.* $g3files){
+ files=($files -f $i)
+}
+
+switch($view){
+case yes
+ page $header.* $g3files
+case *
+ upas/qer $files /mail/faxoutqueue fax $user $telno </dev/null
+ rx fax /sys/lib/fax/faxgoose </dev/null
+}
--- /dev/null
+++ b/rc/bin/fedex
@@ -1,0 +1,62 @@
+#!/bin/rc
+
+if(! ~ $#* 1) {
+ echo usage: fedex 123456789012 >[1=2]
+ exit usage
+}
+
+rfork e
+
+fn bgrep{
+pattern=`{echo $1 | sed 's;/;\\&;'}
+shift
+
+@{ echo 'X {
+$
+a
+
+.
+}
+X ,x/(.+\n)+\n/ g/'$pattern'/p' |
+sam -d $* >[2]/dev/null
+}
+}
+
+fn awk2 {
+ awk 'NR%2==1 { a=$0; }
+ NR%2==0 { b=$0; printf("%-30s %s\n", a, b); }
+ ' $*
+}
+
+fn awk3 {
+ awk '{line[NR] = $0}
+ END{
+ i = 4;
+ while(i < NR){
+ what=line[i++];
+ when=line[i];
+ comment="";
+ if(!(when ~ /..\/..\/.... ..:../)){
+ # out of sync
+ printf("%s\n", what);
+ continue;
+ }
+ i++;
+ if(!(line[i+1] ~ /..\/..\/.... ..:../) &&
+ (i+2 > NR || line[i+2] ~ /..\/..\/.... ..:../)){
+ what = what ", " line[i++];
+ }
+ printf("%s %s\n", when, what);
+ }
+ }' $*
+}
+
+# hget 'http://www.fedex.com/cgi-bin/track_it?airbill_list='$1'&kurrent_airbill='$1'&language=english&cntry_code=us&state=0' |
+hget 'http://www.fedex.com/Tracking?action=track&language=english&cntry_code=us&initial=x&mps=y&tracknumbers='$1 |
+ htmlfmt >/tmp/fedex.$pid
+sed -n '/Tracking number/,/^$/p' /tmp/fedex.$pid | awk2
+echo
+sed -n '/Reference number/,/^$/p' /tmp/fedex.$pid | awk2
+echo
+sed -n '/Date.time/,/^$/p' /tmp/fedex.$pid | sed 1,4d | fmt -l 4000 | sed 's/ [A-Z][A-Z] /&\n/g'
+rm /tmp/fedex.$pid
--- /dev/null
+++ b/rc/bin/fshalt
@@ -1,0 +1,108 @@
+#!/bin/rc
+# fshalt [-r] - sync (flush) and, if possible, halt all file servers
+# and optionally reboot
+rfork e
+reboot=no
+switch ($#*) {
+case 0
+case 1
+ reboot=yes
+case *
+ echo usage: $0 '[-r]' >[1=2]
+ exit usage
+}
+
+path=(/bin)
+builtin cd /
+
+setrtc
+
+# start venti flushing
+venti/sync -h localhost >[2]/dev/null &
+venti/sync >[2]/dev/null &
+
+unmount /mnt/consoles >[2]/dev/null
+kill consolefs | rc # don't compete with /mnt/consoles
+sleep 1
+
+f=`{ls /srv/fscons*>[2]/dev/null}
+k=`{ls /srv/kfs*cmd >[2]/dev/null|sort -r}
+
+echo -n syncing...
+for(i in $f) @ {
+ echo -n $i...
+ {
+ echo
+ dial/drain &
+ sleep 2
+ echo fsys all sync
+ if(! dial/expect -t 120 ': ')
+ echo -n 'not synced...' > /dev/cons
+ } < $i >> $i
+}
+
+# flush the last bit of possible fossil traffic
+echo -n venti...
+venti/sync -h localhost >[2]/dev/null &
+venti/sync >[2]/dev/null &
+sleep 5
+
+for (i in $k){
+ echo -n $i...
+ switch($i){
+ case /srv/kfs.cmd
+ disk/kfscmd sync
+ case *
+ disk/kfscmd -n `{echo $i | sed -n 's%/srv/kfs.(.*).cmd%\1%p'} sync
+ }
+ sleep 2
+}
+
+# halting (binaries we run can't be on the fs we're halting)
+ramfs
+builtin cd /tmp
+cp /bin/dial/expect /tmp
+cp /bin/echo /tmp
+cp /bin/disk/kfscmd /tmp
+cp /bin/rc /tmp
+cp /bin/sed /tmp
+cp /bin/ns /tmp
+cp /bin/iostats /tmp
+mkdir /tmp/lib
+cp /rc/lib/rcmain /tmp/lib
+bind /tmp /rc
+bind /tmp /bin
+
+# put this in a shell function so this rc script doesn't get read
+# when it's no longer accessible
+fn x {
+ echo
+ echo -n halting...
+ for(i in $f) @ {
+ echo -n $i...
+ {
+ echo fsys all halt
+ if(! expect -t 60 ': ')
+ echo -n 'not halted...' > /dev/cons
+ } < $i >> $i
+ }
+
+ for (i in $k){
+ echo -n $i...
+ switch($i){
+ case /srv/kfs.cmd
+ kfscmd halt
+ case *
+ kfscmd -n `{echo $i | sed -n 's%/srv/kfs.(.*).cmd%\1%p'} halt
+ }
+ }
+ echo
+ echo done halting
+
+ if (~ $reboot yes) {
+ echo rebooting...
+ echo reboot >'#c/reboot'
+ }
+}
+
+x
--- /dev/null
+++ b/rc/bin/go.fishing
@@ -1,0 +1,15 @@
+#!/bin/rc
+# go.fishing - set up vacation responder
+rfork e
+
+cd /mail/box/$user
+if (test -e gone.fishing) {
+ echo $0: /mail/box/$user/gone.fishing already exists >[1=2]
+ exit 'already fishing'
+}
+
+>gone.addrs
+chmod -a gone.addrs
+>gone.addrs
+chmod +arw gone.addrs
+>>gone.fishing
--- /dev/null
+++ b/rc/bin/homespool
@@ -1,0 +1,17 @@
+#!/bin/rc
+
+echo creating spool directory
+mkdir $home/spool
+chmod 777 $home/spool
+echo creating ctrl directory
+mkdir $home/spool/ctrl
+chmod 775 $home/spool/ctrl
+echo creating seqno file
+touch $home/spool/ctrl/seqno
+echo creating options file
+chmod 222 $home/spool/ctrl/seqno
+cat >$home/spool/ctrl/options <<EOF
+facedown
+nobanner
+ $user
+EOF
--- /dev/null
+++ b/rc/bin/ipconf/inside
@@ -1,0 +1,19 @@
+#!/bin/rc
+
+ip/ipconfig
+
+# supply unknowns with inside addresses
+if( ! grep -s 'auth=' /net/ndb){
+ echo ' auth=135.104.9.7'>>/net/ndb
+ echo ' authdom=cs.bell-labs.com'>>/net/ndb
+}
+if( ! grep -s 'ntp=' /net/ndb)
+ echo ' ntp=135.104.9.2'>>/net/ndb
+if( ! grep -s 'dns=' /net/ndb){
+ echo ' dns=135.104.8.38'>>/net/ndb
+ echo ' dns=135.104.70.11'>>/net/ndb
+}
+
+# start dns if it isn't already going
+if(! test -e /srv/dns )
+ ndb/dns -r
--- /dev/null
+++ b/rc/bin/ipconf/lra
@@ -1,0 +1,92 @@
+#!/bin/rc
+
+# on hook and initialize
+fn initfn {
+ dial/drain
+ dial/at -q -t 5 zh0
+}
+
+# dial telephone number
+fn dialfn {
+ dial/drain
+ dial/at -q -t 60 dt^$1
+}
+
+# process options
+for(i in $*){
+ switch($i){
+ case '-P'
+ primary=-P
+ }
+}
+
+# the following can be inherited
+switch($dev){
+case ''
+ dev=/dev/eia1
+}
+switch($telno){
+case ''
+ telno=18009878722
+}
+switch($baud){
+case ''
+ baud=115200
+}
+
+{
+ # set up uart
+ if( test -e $dev^ctl ){
+ echo -n b^$baud # baud rate
+ echo -n m1 # cts/rts flow control
+ echo -n q64000 # big buffer
+ echo -n n1 # nonblocking writes
+ echo -n r1 # rts on
+ echo -n d1 # dtr on
+ echo -n c1 # handup wen we lose dcd
+ } > $dev^ctl
+
+ # get the modem's attention
+ while( ! initfn )
+ sleep 1
+
+ # dial
+ while( ! dialfn $telno )
+ sleep 30
+
+ if( ! dial/expect -it 60 'username:' ){
+ echo lra: can''t connect >[1=2]
+ exit connect
+ }
+ dial/pass
+ if( ! dial/expect -it 60 'password:' ){
+ echo lra: can''t connect >[1=2]
+ exit connect
+ }
+ dial/pass
+ if( ! dial/expect -t 60 'telnet:' ){
+ echo lra: can''t connect >[1=2]
+ exit connect
+ }
+ echo ppp
+ echo connected to lra >[1=2]
+
+ # start ppp
+ ip/ppp $primary -f
+} < $dev > $dev
+
+# supply unknowns with inside addresses
+if( ! grep -s 'auth=' /net/ndb){
+ echo ' auth=135.104.9.7'>>/net/ndb
+ echo ' authdom=cs.bell-labs.com'>>/net/ndb
+}
+if( ! grep -s 'ntp=' /net/ndb)
+ echo ' ntp=135.104.9.2'>>/net/ndb
+if( ! grep -s 'dns=' /net/ndb){
+ echo ' dns=135.104.8.38'>>/net/ndb
+ echo ' dns=135.104.70.11'>>/net/ndb
+}
+
+# start dns if it isn't already going
+if(! test -e /srv/dns )
+ ndb/dns -r
--- /dev/null
+++ b/rc/bin/ipconf/outside
@@ -1,0 +1,24 @@
+#!/bin/rc
+ip/ipconfig -dDG
+
+# supply unknowns with outside addresses
+if( ! grep -s 'auth=' /net/ndb){
+ echo ' auth=204.178.31.3'>>/net/ndb
+ echo ' authdom=cs.bell-labs.com'>>/net/ndb
+}
+if( ! grep -s 'ntp=' /net/ndb)
+ echo ' ntp=204.178.31.2'>>/net/ndb
+if( ! grep -s 'dns=' /net/ndb){
+ echo ' dns=204.178.31.3'>>/net/ndb
+ echo ' dns=204.178.31.4'>>/net/ndb
+}
+
+# set ndbfile for termrc touse
+NDBFILE=/lib/ndb/external
+
+# start dns if it isn't already going
+if(! test -e /srv/dns )
+ ndb/dns -r
+
+# just in case we can't find achille
+cpu=tcp!204.178.31.2
--- /dev/null
+++ b/rc/bin/ipconf/theworld
@@ -1,0 +1,76 @@
+#!/bin/rc
+
+fn initfn {
+ dial/flush
+ echo +++
+ echo -n atzh0
+ dial/expect -q -t 5 OK
+}
+
+fn dialfn {
+ dial/flush
+ echo -n atdt^$telno^
+ dial/expect -q -t 60 CONNECT
+}
+
+# process options
+for(i in $*){
+ switch($i){
+ case '-P'
+ primary=-P
+ }
+}
+
+switch($dev){
+case ''
+ dev=/dev/eia1
+}
+switch($telno){
+case ''
+ telno=18009878722
+}
+switch($baud){
+case ''
+ baud=115200
+}
+
+{
+ # set up uart
+ if( test -e $dev^ctl ){
+ echo -n b^$baud
+ echo -n m1 # cts/rts flow control
+ echo -n q64000 # big buffer
+ echo -n n1 # nonblocking writes
+ echo -n r1 # rts on
+ echo -n d1 # dtr on
+ echo -n c1 # handup wen we lose dcd
+ } > $dev^ctl
+
+ # get the modem's attention
+ while( ! initfn )
+ sleep 1
+
+ # dial
+ while( ! dialfn )
+ sleep 30
+ echo connected to the world >[1=2]
+
+ # start ppp
+ ip/ppp $primary -f
+} < $dev > $dev
+
+# supply unknowns with outside addresses
+if( ! grep -s 'auth=' /net/ndb){
+ echo ' auth=204.178.31.3'>>/net/ndb
+ echo ' authdom=cs.bell-labs.com'>>/net/ndb
+}
+if( ! grep -s 'ntp=' /net/ndb)
+ echo ' ntp=204.178.31.2'>>/net/ndb
+if( ! grep -s 'dns=' /net/ndb){
+ echo ' dns=204.178.31.3'>>/net/ndb
+ echo ' dns=204.178.31.4'>>/net/ndb
+}
+
+# start dns if it isn't already going
+if(! test -e /srv/dns )
+ ndb/dns -r
--- /dev/null
+++ b/rc/bin/ipso
@@ -1,0 +1,163 @@
+#!/bin/rc
+# ipso - edit secstore files, reload factotum keys
+if(! ~ $service terminal &&
+ ! ~ $user `{ ls -ld /mnt/factotum/ctl | awk '{print $4}' }){
+ echo >[1=2] ipso should be run only on the terminal
+ exit terminal
+}
+
+rfork e
+path=(/bin)
+home=(/tmp)
+editor = (acme -c1)
+name = secstore
+get = secstoreget
+put = secstoreput
+edit = no
+load = no
+flush = no
+
+fn secstoreget{
+ auth/secstore -i -g $1 <_password
+}
+
+fn secstoreput{
+ auth/secstore -i -p $1 <_password
+}
+
+fn aesget{
+ if(! ~ $1 /*){
+ echo >[1=2] ipso: aescbc requires fully qualified pathname
+ exit usage
+ }
+ auth/aescbc -i -d < $1 > `{basename $1} <[3] _password
+}
+
+fn aesput{
+ auth/aescbc -i -e > $1 < `{basename $1} <[3] _password
+}
+
+fn editedfiles{
+ if(~ $get aesget){
+ for(i in $files)
+ if(ls -tr | sed '1,/^_timestamp$/d' | grep -s '^'^`{basename $i}^'$')
+ echo $i
+ }
+ if not
+ ls -tr | sed '1,/^_timestamp$/d'
+}
+
+edexp=`{grep '^editor=' /mnt/plumb/rules >[2]/dev/null}
+if(~ $#edexp 1)
+ eval $edexp
+
+while(~ $1 -*){
+ switch($1){
+ case -s
+ editor = sam
+ case -a
+ name = aescbc
+ get = aesget
+ put = aesput
+ case -f
+ flush = yes
+ case -e
+ edit = yes
+ case -l
+ load = yes
+ case *
+ echo >[2=1] 'usage: ipso [-a -f -e -l] [-s] [file ...]'
+ exit usage
+ }
+ shift
+}
+
+if(~ $flush no && ~ $edit no && ~ $load no){
+ load = yes
+ edit = yes
+ flush = yes
+}
+
+if(~ $flush yes && ~ $edit no && ~ $load no){
+ echo flushing old keys
+ echo delkey > /mnt/factotum/ctl
+ exit 0
+}
+
+if(~ $get aesget && ~ $#* 0){
+ echo >[2=1] ipso: must specify a fully qualified file name for aescbc '(-a)'
+ exit usage
+}
+
+rfork ne
+ramfs -p >[2] /dev/null # silence 'i/o on hungup channel' message at exit
+unmount /mnt/plumb
+bind -c /tmp /srv
+builtin cd /tmp
+
+if ( ~ $edit yes ) echo '
+ Warning: The editor will display the secret contents of
+ your '$name' files in the clear.
+'
+# get password and remember it
+{
+ echo rawon
+ echo -n $name password: >/dev/cons
+ read > _password
+ echo > /dev/cons
+}</dev/cons > /dev/consctl
+
+# get list of files
+if(~ $#* 0){
+ if(! auth/secstore -G . -i < _password > _listing){
+ echo 'secstore read failed - bad password?'
+ sleep 2
+ exit password
+ }
+ files=`{sed 's/[ ]+.*//' _listing}
+}
+if not
+ files = $*
+
+# copy the files to local ramfs
+for(i in $files){
+ if(! $get $i){
+ echo $name ' read failed - bad password?'
+ sleep 2
+ exit password
+ }
+}
+sleep 2; date > _timestamp # so we can find which files have been edited.
+
+# edit the files
+if(~ $edit yes) $editor `{for(i in $files) basename $i}
+if(~ $flush yes ){
+ echo flushing old keys
+ echo delkey > /mnt/factotum/ctl
+}
+if(~ $load yes){
+ echo loading factotum keys
+ if (~ factotum $files) read -m < factotum > /mnt/factotum/ctl
+}
+
+# copy the files back
+for(i in `{editedfiles}){
+ echo -n copy ''''`{basename $i}^'''' back?' [y/n/x]'
+ switch(`{read}){
+ case [yY]*
+ if(! $put $i){
+ echo $name ' read failed - bad password?'
+ sleep 2
+ exit password
+ }
+ echo ''''$i'''' copied to $name
+ if(~ $i factotum)
+ read -m < $i > /mnt/factotum/ctl
+ case [xXqQ]*
+ exit
+ case [nN]* *
+ echo ''''$i'''' skipped
+ }
+}
+
+exit ''
--- /dev/null
+++ b/rc/bin/ipv6on
@@ -1,0 +1,94 @@
+#!/bin/rc
+# ipv6on [netdir ndbfile [gwv4]] - configure an interface for ipv6,
+# once ipv4 is configured.
+if (! ~ $#* 0 2 3) {
+ echo usage: $0 '[netdir ndbfile [gw-v4-name]]' >[1=2]
+ exit usage
+}
+rfork e
+if (~ $#* 0) {
+ netdir=/net
+ ndbf=/lib/ndb/local
+ gw=`{ndb/ipquery sys $sysname ipgw | sed 's/ipgw=//'}
+}
+if not {
+ netdir=$1
+ ndbf=$2
+ if (~ $#* 2)
+ # gw=()
+ gw=`{ndb/ipquery sys $sysname ipgw | sed 's/ipgw=//'}
+ if not
+ gw=$3
+}
+if (~ $netdir /net) {
+ xsfx=()
+ xdir=()
+}
+if not {
+ xsfx=(-x `{echo $netdir | sed 's;^/net;;'})
+ xdir=(-x $netdir)
+}
+
+fn nonnil { # variable
+ if (~ $#$1 0) {
+ echo no ip for $1
+ exit no-ip
+ }
+ if (! ~ $#$1 1) {
+ echo multiple ips for $1
+ exit multiple-ips
+ }
+}
+
+#
+# configure v6 for link-local addresses (fe80::) & multicast (ff02::)
+#
+if (! ip/ipconfig -6 $xdir ether $netdir/ether?)
+ exit 'ipconfig -6 failed'
+ip/ipconfig $xdir ether $netdir/ether? ra6 recvra 1
+
+mev6=`{ndb/query -f $ndbf sys $sysname ipv6}
+if (~ $#sysname 0 || ~ $sysname '')
+ mev6=`{ndb/query -f $ndbf sys $sysname ip | grep :}
+# mev4=`{ndb/query -f $ndbf sys $sysname ip | grep -v :}
+
+# for testing
+mylnk=`{ip/linklocal `{cat $netdir/ether?/addr}}
+nonnil mylnk
+
+if (~ $#gw 1) {
+ if (~ $gw [0-9]*.[0-9]*.[0-9]*.[0-9]*)
+ gwv4 = $gw
+ if (~ $#gwv4 0 || ~ $gwv4 '') # assume namev6 and name
+ gwv4=`{ndb/query -f $ndbf sys $gw ip}
+ gwv6=`{ndb/query -f $ndbf sys $gw ipv6}
+
+ if (! ~ $#gwv4 0) {
+ # echo ping gw $gwv4...
+ # load arp cache with gw mac
+ ip/ping -qn 3 $netdir/icmp!$gwv4 >/dev/null >[2=1] &
+ sleep 1 # wait for ping
+
+ gweth=`{grep '* '^$gwv4^' ' $netdir/arp | awk '{print $4}' }
+ nonnil gweth
+ gwlnk=`{ip/linklocal $gweth}
+ nonnil gwlnk
+ }
+}
+nonnil mev6
+#
+# configure my global v6 addresses
+#
+ip/ipconfig $xdir ether $netdir/ether? add $mev6 /64
+ip/ipconfig $xdir loopback /dev/null add $mev6 /128
+
+if (~ $#gw 1) {
+ if (~ $#gwv6 0 || ~ $gwv6 '')
+ gwv6=`{ip/linklocal $gweth}
+ nonnil gwv6
+ #
+ # add default v6 route to v6 addr of v4 gw
+ #
+ echo add :: /0 $gwv6 >$netdir/iproute # need not be link-local
+}
+exit ''
--- /dev/null
+++ b/rc/bin/iwhois
@@ -1,0 +1,87 @@
+#!/bin/rc
+# iwhois [-n] domain - print registration data for domain
+rfork e
+if (~ $#* 1 && ~ $1 -n)
+ noboiler=yes
+person=`{echo $1|sed s/@.*//}
+fn boilerplate { sed -n '/^[ ]*[A-Za-z][A-Za-z]*:$/,$p' $* }
+
+switch($1){
+case *@*
+ machine=`{echo $1|sed s/.*@//}
+case *.ca
+ machine=whois.cira.ca
+ fn boilerplate { grep -v ':[ ]*$' $* }
+case *.us
+ machine=whois.nic.us
+ fn boilerplate { sed '/^>* Whois database was last updated on/,$d' $* }
+case *.co.uk *.net.uk *.org.uk
+ machine=whois.nic.uk
+ fn boilerplate { sed '/^ +WHOIS database last updated at/,$d' $* }
+case *.ac.uk
+ machine=whois.ja.net
+case *.au
+ machine=whois.aunic.net
+ fn boilerplate { grep -v ':[ ]*$' $* }
+case *.be
+ machine=whois.dns.be
+ person='-T dn '^$person
+ fn boilerplate { cat $* }
+case *.cn
+ machine=whois.cnnic.net.cn
+ fn boilerplate { cat $* }
+case *.de
+ machine=whois.denic.de
+ person='-T dn '^$person
+ fn boilerplate { cat $* }
+case *.dk
+ machine=whois.dk-hostmaster.dk
+ fn boilerplate { grep -v '^#' $* }
+case *.es
+ echo no known whois server for .es
+ exit
+case *.fr
+ machine=whois.nic.fr
+ fn boilerplate { grep -v '^%%' $* }
+case *.in
+ machine=whois.inregistry.net
+ fn boilerplate { cat $* }
+case *.jp
+ machine=whois.jprs.jp
+ person=$person^'/e'
+ fn boilerplate { cat $* }
+case *.se
+ machine=whois.nic-se.se
+ fn boilerplate { grep -v '^#' $* | uniq }
+case [0-9]*.[0-9]*.[0-9]*.[0-9]*
+ machine=whois.arin.net
+ fn boilerplate { cat $* }
+case *
+ machine=whois.internic.net # alternate: whois.networksolutions.com
+ fn boilerplate { cat $* }
+}
+if (~ $noboiler yes)
+ fn boilerplate { cat $* }
+file=/tmp/iwhois$pid
+fn sigexit {
+ rm -f $file
+}
+echo $person | telnet -nr tcp!$machine!whois > $file
+x=`{ sed -n -e 's/.*Whois Server: (.*)/\1/p' \
+ -e 's;.*ReferralServer: whois://(.*)(:43)?;\1;p' $file }
+switch($#x){
+case 0
+ ; # e.g., for .ca
+case 1
+ # chase the referral chain
+ echo $person | telnet -nr tcp!$x!whois > $file
+case *
+# echo $0: buggery: `{echo $x | tr ' ' '\12' | sort -u} >[1=2]
+ echo $person | telnet -nr tcp!^$x(1)^!whois > $file
+}
+if (test ! -s $file) {
+ echo $0: broken whois server tcp!$x!whois returned no data >[1=2]
+ exit broken
+}
+boilerplate $file
+rm $file
--- /dev/null
+++ b/rc/bin/juke
@@ -1,0 +1,60 @@
+#!/bin/rc
+
+wide=`{echo $vgasize | sed 's/(.*)x.*x.*/\1 > 240/' | hoc}
+
+debug=0
+tflag=''
+wflag=''
+host=''
+kb=4096
+flags=()
+sname=$user
+if (! ~ $wide 1) {
+ flags=($flags -t)
+ kb=1024
+}
+while(! ~ $#* 0) {
+ switch ($1) {
+ case -d
+ debug=$2
+ shift
+ case -t
+ tflag='-t'
+ case -h
+ host=$2
+ shift
+ case -w
+ wflags='-w'
+ case -s
+ sname=$2
+ shift
+ case -*
+ echo Usage: classical [-d level] [-t] [-h srvhost]
+ exit usage
+ }
+ shift
+}
+if (! test -e /mnt/playlist){
+ if (! ~ $debug '0') echo mounting playlistfs
+ if (! test -e /srv/playlist.$sname && ! ~ $host ''){
+ import -a $host /srv /srv
+ }
+ if (! mount -b /srv/playlist.$sname /mnt >/dev/null >[2]/dev/null){
+ rm -f /srv/playlist.$sname
+ if (! ~ $debug '0') echo starting playlistfs
+ games/playlistfs -s $sname -d $debug
+ }
+}
+if (! test -w /mnt/juke) {
+ if (! test -e /srv/jukefs.$sname && ! ~ $host ''){
+ import -a $host /srv /srv
+ }
+ if (! mount -b /srv/jukefs.$sname /mnt >/dev/null >[2]/dev/null){
+ if (! ~ $debug '0') echo games/jukefs
+ games/jukefs -s $sname
+ }
+}
+if (~ $wflags '-w') {
+ exec games/jukebox -w -d $debug $tflag &
+}
+exec games/jukebox -d $debug $tflag
--- /dev/null
+++ b/rc/bin/kill
@@ -1,0 +1,4 @@
+#!/bin/rc
+for(i){
+ ps | sed -n '/ '^$i^'$/s%^[^ ]* *([^ ]*).*%chmod 666 /proc/\1/ctl;echo kill > /proc/\1/ctl%p'
+}
--- /dev/null
+++ b/rc/bin/kmem
@@ -1,0 +1,31 @@
+#!/bin/rc
+# kmem [kernel] - print summary of allocate blocks in running kernel
+rfork e
+if(! ~ $#* 0 1){
+ echo 'usage: kmem [kernel]' >[1=2]
+ exit usage
+}
+
+if(~ $#* 1)
+ binary=$1
+
+echo 'kinit(); blocksummary()' | acid -k -lkernel -lpool -lleak $pid $binary | awk '
+ $1 == "block" {
+ addr=$6
+ size=$3
+ alloc=$4
+ total[alloc] += size
+ count[alloc]++
+ }
+ $1 == "summary" {
+ alloc=$2
+ cnt=$3
+ size=$4
+ total[alloc] += size
+ count[alloc] += cnt
+ }
+ END{
+ for(i in count)
+ printf("%6d %11d %s\n", count[i], total[i], i);
+ }
+' | sort -nr
--- /dev/null
+++ b/rc/bin/label
@@ -1,0 +1,6 @@
+#!/bin/rc
+# label word ... - write words into our label, if any
+if (test -w /dev/label)
+ echo -n $* > /dev/label
+if not if (test -w /mnt/term/dev/label)
+ echo -n $* > /mnt/term/dev/label
--- /dev/null
+++ b/rc/bin/lc
@@ -1,0 +1,2 @@
+#!/bin/rc
+ls -p $* | mc
--- /dev/null
+++ b/rc/bin/leak
@@ -1,0 +1,95 @@
+#!/bin/rc
+
+rfork e
+
+flagfmt='a,b,c,d,s,f binary,r res,x width'
+args='name | pid list'
+if(! ifs=() eval `{aux/getflags $*} || ~ $#* 0){
+ aux/usage
+ exit usage
+}
+
+conflicting=($flagb $flagc $flags)
+if(~ $#conflicting 2 || ~ $#conflicting 3){
+ echo 'can only use one of -b, -c or -s' >[1=2]
+ exit usage
+}
+
+leakflags=()
+if(~ $#flags 1)
+ leakflags=($leakflags -s)
+if(~ $#flaga 1)
+ leakflags=($leakflags -a)
+if(~ $#flagc 1)
+ leakflags=($leakflags -c)
+if(~ $#flagd 1)
+ leakflags=($leakflags -d)
+if(~ $#flagf 1)
+ leakflags=($leakflags -f $flagf)
+
+acidleakflags=()
+if(~ $#flagb 1)
+ acidleakflags=($acidleakflags -b)
+if(~ $#flagr 1)
+ acidleakflags=($acidleakflags -r $flagr)
+if(~ $#flagx 1)
+ acidleakflags=($acidleakflags -x $flagx)
+
+if(! test -d /proc/$1) {
+ # x=`{psu | awk '$NF=="'$1'" {print $2}'}
+ x=`{psu | grep ' '$1'$' | sed 's/^[^ ]+ +([0-9]+).*/\1/'}
+ if(~ $#x 0) {
+ echo 'no processes named '$1 >[1=2]
+ exit usage
+ }
+ echo leak $leakflags $acidleakflags $x
+ exit
+}
+
+pidlist=`{echo $"* | tr ' ' ,}
+
+echo 'leakdump({'$pidlist'})' | acid -lpool -lleak $1 $flagf |
+{
+ if(~ $#flaga 1 && ~ $#flagd 1)
+ grep 'block|free'
+ if not
+ if(~ $#flaga 1)
+ grep block
+ if not
+ if(~ $#flagd 1)
+ grep free
+ if not
+ aux/acidleak $acidleakflags $flagf
+} |
+{
+ if(~ $#flags 1)
+ awk '{print $4}' |
+ sort | uniq -c | sort -nr |
+ sed 's! *(.*) (0x.*)!src(\2); // \1!'
+ if not
+ if(~ $#flagc 1)
+ awk 'BEGIN {
+ for(i=0; i<16; i++)
+ _unhex[sprintf("%x", i)] = _unhex[sprintf("%X", i)] = i
+ }
+ function unhex(s, i, v) {
+ sub("^0[xX]0*","",s)
+ for (i=1; i<=length(s); i++)
+ v = v*16 + _unhex[substr(s,i,1)]
+ return v
+ }
+ { sum[$4] += unhex($3);
+ count[$4]++;
+ alloc[$4] = $6;
+ }
+ END {
+ for (v in sum) {
+ printf("src(%s);\t// %d\t%d\t%d\t%s\n", v, sum[v], count[v], sum[v] / count[v], alloc[v])
+ total += sum[v]
+ }
+ printf("// %d\n", total);
+ }
+ ' | sort -nr +2
+ if not
+ cat
+}
--- /dev/null
+++ b/rc/bin/lookman
@@ -1,0 +1,36 @@
+#!/bin/rc
+# Usage: lookman key ...
+# prints out the names of all manual pages containing all the given keywords
+rfork e
+index=/sys/lib/man/lookman/index
+t1=/tmp/look1.$pid
+t2=/tmp/look2.$pid
+fn sigexit {
+ rm -f $t1 $t2
+ exit
+}
+fn sigint sighup sigterm {
+ rm -f $t1 $t2
+ exit note
+}
+
+*=`{echo $*|tr A-Z a-z|tr -dc 'a-z0-9_. \012'} # fold case, delete funny chars
+if(~ $#* 0){
+ echo Usage: lookman key ... >/fd/2
+ exit usage
+}
+look $1 $index | sed 's/.* //' | sort -u >$t1
+shift
+for(i in $*){
+ look $i $index | sed 's/.* //' | sort -u |
+ awk 'BEGIN {
+ while (getline < "'$t1'" > 0)
+ table[$0] = 1
+ }
+ { if (table[$0]) print }
+ ' > $t2
+ mv $t2 $t1
+}
+sort $t1 | sed 's;/sys/man/;;
+ s;(.*)/(.*);man \1 \2 # \2(\1);'
+exit ''
--- /dev/null
+++ b/rc/bin/lp
@@ -1,0 +1,212 @@
+#!/bin/rc
+# lp - enqueues the file to be printed and starts the daemon, when necessary.
+# Make changes to /sys/src/cmd/lp/lp.rc;
+# changes made directly to /rc/bin/lp will be lost.
+
+rfork en # so that environment and name space are not polluted
+#
+# put 'fn sigexit { rm /tmp/lpcrap; exit interrupted }' into processes that create /tmp/lpcrap.
+
+ifs='
+' # set ifs in case it is munged in user's environment
+
+LPLIB=/sys/lib/lp # lp scripts directories and configuration file are here
+LPBIN=/$cputype/bin/aux # lp specific binaries are here
+LPSPOOL=$LPLIB/queue # lp queues
+LPLOGDIR=$LPLIB/log # lp logs
+
+$LPLIB/bin/lpscratch
+x=$status
+if(! ~ $x '') exit $x
+
+# build /bin from the ground up
+bind /$cputype/bin /bin # general compiled binaries
+bind -a /rc/bin /bin # general rc scripts
+# This needs to be fixed for the real thing
+bind -a $LPLIB/bin /bin # lp specific rc scripts
+bind -a $LPBIN /bin # lp specific compiled binaries
+path=(/bin)
+
+if (! test -w /tmp) bind -bc $LPLIB/tmp /tmp
+
+USAGE='usage: lp [-d printer] [-p process] [options] [files]
+ lp [-d printer] -q
+ lp [-d printer] -k jobnos
+
+ options include:
+ -D turn on debugging output
+ -H no header
+ -L landscape mode
+ -M<mach> print on machine <mach>
+ -Q put task only into the queue
+ -R restart printer daemon
+ -c<n> make <n> copies
+ -f<font.size> specify font and size
+ -i<src> take media from <src> input bin
+ -l<n> print <n> lines per logical page
+ -m<n> magnify <n> times
+ -n<n> print <n> logical pages per physical page
+ -o<i-j,k> print only pages i-j and k
+ -r reverse pages
+ -u<userid> print as <userid>
+ -x<n> x page offset in inches
+ -y<n> y page offset in inches
+'
+
+# umask 000 # this doesn't work in plan 9
+if (~ $#sysname 0)
+ THIS_HOST=plan9
+if not {
+ THIS_HOST=`{ndb/query sys $sysname dom}
+ if(~ $#THIS_HOST 0)
+ THIS_HOST=$sysname
+}
+
+LPMACHID=$THIS_HOST
+THIS_USERID=$user
+LPUSERID=$THIS_USERID
+LPLOC=''
+
+# Set default printer to be output device
+if (~ $#LPDEST 0 && test -f $LPLIB/defdevice) LPDEST=`{cat $LPLIB/defdevice}
+
+# option parameters
+COPIES=1
+FONT=''
+IBIN=''
+KILLFLAG=0
+LAND=''
+LINES=''
+LPQ=0
+MAG=''
+NOHEAD=''
+NPAG=''
+OLIST=''
+POINT=''
+RESET=''
+REVERSE=''
+QONLY=''
+TRAY=''
+XOFF=''
+YOFF=''
+
+# Process options
+flagfmt='D,H,L,Q,R,r,q,M mach,c copies,d printer,f font.size,i src,k jobnos,l lines,m magnify,n lpages,o pages,p proc,u userid,x offset,y offset'
+argv0=lp
+
+if(! ifs=() eval `{aux/getflags $*}) {
+ echo $USAGE
+ exit usage
+}
+if(~ $flagd '?'){
+ awk 'BEGIN {print "device location host class"}
+/^[^#]/ { printf "%-12s %-9s %-22s %s\n", $1, $2, $3, $6 }' $LPLIB/devices
+ exit
+}
+if(~ $flagp '?'){
+ ls $LPLIB/process
+ exit
+}
+
+if (! ~ $#flagD 0) { DEBUG=1; flag x + }; if not { DEBUG=''; flag x - }
+if (! ~ $#flagH 0) NOHEAD=1
+if (! ~ $#flagL 0) LAND=1
+if (! ~ $#flagM 0 && ~ $LPUSERID daemon) LPMACHID=$flagM
+if (! ~ $#flagQ 0) QONLY=1
+if (! ~ $#flagR 0) RESET=1
+if (! ~ $#flagc 0) COPIES=$flagc
+if(! ~ $#flagd 0) LPDEST=$flagd
+if (! ~ $#flagf 0) eval `{echo $flagf | sed -e 's/([^.]*)\.([0-9.]*)/FONT=\1;POINT=\2;/'}
+if (! ~ $#flagi 0) IBIN=$flagi
+if (! ~ $#flagk 0) KILLFLAG=1
+if (! ~ $#flagl 0) LINES=$flagl
+if (! ~ $#flagm 0) MAG=$flagm
+if (! ~ $#flagn 0) NPAG=$flagn
+if (! ~ $#flago 0) OLIST=-o^$flago
+if (! ~ $#flagp 0) LPPROC=$flagp
+if (! ~ $#flagq 0) LPQ=1
+if (! ~ $#flagr 0) REVERSE=1
+if (! ~ $#flagu 0) LPUSERID=$flagu
+if (! ~ $#flagx 0) XOFF=$flagx
+if (! ~ $#flagy 0) YOFF=$flagy
+
+if (~ $#LPDEST 0) {
+ echo 'Set environment variable LPDEST or use the
+''-d printer'' option to set the destination.' >[1=2]
+ exit 'LPDEST not set'
+}
+if (~ $LPDEST */*) { # handles MHCC destinations like mh/lino
+ LPLOC=`{echo $LPDEST|sed 's/^(.*)\/(.*)/\1/'}
+ LPDEST=`{echo $LPDEST|sed 's/^(.*)\/(.*)/\2/'}
+}
+
+# look up device, get info
+LPDLINE=`{grep '^'$LPDEST'[ ]' $LPLIB/devices}
+if (! ~ $status '') {
+ echo 'device '$LPDEST' is not in '$LPLIB'/devices' >[1=2]
+ exit 'LPDEST is bad'
+}
+LOC=$LPDLINE(2)
+DEST_HOST=$LPDLINE(3)
+OUTDEV=$LPDLINE(4)
+SPEED=$LPDLINE(5)
+LPCLASS=$LPDLINE(6)
+if (~ $#LPPROC 0) LPPROC=$LPDLINE(7)
+SPOOLER=$LPDLINE(8)
+STAT=$LPDLINE(9)
+KILL=$LPDLINE(10)
+DAEMON=$LPDLINE(11)
+SCHED=$LPDLINE(12)
+
+if (~ $LPCLASS *nohead*)
+ NOHEAD=1
+if (~ $LPCLASS *duplex*)
+ DUPLEX=1
+
+if (~ $#SCHED 0) SCHED=FIFO # everyone uses FIFO
+if (~ $KILLFLAG 1)
+ switch ($KILL) {
+ case -; echo kill option not available on $LPDEST >[1=2]
+ exit 'kill n/a'
+ case *; bind -b $LPLIB/kill /bin
+ exec $KILL $*
+ exit 'kill command '"$KILL"' not found'
+ }
+if (~ $LPQ 1)
+ switch ($STAT) {
+ case -; echo queue status option not available on $LPDEST >[1=2]
+ exit 'stat option not available'
+ case *; bind -b $LPLIB/stat /bin
+ exec $STAT $* < /dev/null
+ exit 'stat command '"$STAT"' not found'
+ }
+DATE=`{date}
+LPLOG=$LPLOGDIR/$LPDEST
+if (! test -e $LPLOG) {
+ >$LPLOG
+ chmod +rwa $LPLOG >[2]/dev/null
+}
+
+if (~ $RESET '') {
+ switch ($SPOOLER) {
+ case -; echo spooler does not exist for $LPDEST >[1=2]
+ exit 'no spooler'
+ case *; bind -b $LPLIB/spooler /bin
+ if (~ $#* 0) $SPOOLER
+ if not $SPOOLER $*
+ }
+}
+if not {
+ echo restarting daemon for printer $LPDEST >[1=2]
+ UNLOCK $LPSPOOL/$LPDEST
+ sleep 5
+}
+
+# run daemon
+if (~ $QONLY '') {
+ if (! ~ $DAEMON -) {
+ bind -b $LPLIB/daemon /bin
+ $DAEMON $* >>$LPLOG >[2=1] &
+ }
+}
+exit ''
--- /dev/null
+++ b/rc/bin/mail
@@ -1,0 +1,12 @@
+#!/bin/rc
+switch($#*){
+case 0
+ exec upas/nedmail
+}
+
+switch($1){
+case -f* -r* -c* -m*
+ exec upas/nedmail $*
+case *
+ exec upas/marshal $*
+}
--- /dev/null
+++ b/rc/bin/man
@@ -1,0 +1,149 @@
+#!/bin/rc
+# man - print manual pages
+rfork e
+
+. /sys/man/fonts
+
+cmd=n
+sec=()
+S=/sys/man
+d=0
+
+fn roff {
+ preproc=()
+ postproc=cat
+ x=`{doctype $2}
+ if (~ $1 t) {
+ if(~ $x *grap*)
+ preproc=($preproc grap)
+ if(~ $x *pic*)
+ preproc=($preproc pic)
+ Nflag=-Tutf
+ }
+ if not {
+ Nflag='-N'
+ Lflag='-rL1000i'
+ # setting L changes page length to infinity (sed script removes empty lines)
+ if (grep -s '^\.(2C|sp *[0-9]*\.)' $2)
+ postproc=col
+ }
+ if(~ $x *eqn*)
+ preproc=($preproc eqn)
+ if(~ $x *tbl*)
+ preproc=($preproc tbl)
+ {echo -n $FONTS; cat $2 </dev/null} |
+ switch($#preproc) {
+ case 0
+ troff $Nflag $Lflag -$MAN
+ case 1
+ $preproc | troff $Nflag $Lflag -$MAN
+ case 2
+ $preproc(1) | $preproc(2) | troff $Nflag $Lflag -$MAN
+ case 3
+ $preproc(1) | $preproc(2) | $preproc(3) |
+ troff $Nflag $Lflag -$MAN
+ case *
+ $preproc(1) | $preproc(2) | $preproc(3) |
+ $preproc(4) | troff $Nflag $Lflag -$MAN
+ } | $postproc
+}
+
+fn page {
+ if(test -d /mnt/wsys/acme)
+ /bin/page -w
+ if not
+ /bin/page
+}
+
+
+search=yes
+while(~ $d 0) {
+ if(~ $#* 0) {
+ echo 'Usage: man [-bntpPSw] [0-9] [0-9] ... name1 name2 ...' >[1=2]
+ exit
+ }
+ if(test -d $S/$1){
+ sec=($sec $1)
+ shift
+ }
+ if not
+ switch($1) {
+ case -b ; cmd=b ; shift
+ case -n ; cmd=n ; shift
+ case -P ; cmd=P ; shift
+ case -p ; cmd=p ; shift
+ case -S ; search=no ; shift
+ case -t ; cmd=t ; shift
+ case -w ; cmd=w ; shift
+ case * ; d=1
+ }
+}
+if(~ $#sec 0) {
+ sec=`{ls -pd $S/[0-9]* }
+}
+ix=$S/$sec/INDEX
+if(~ $#* 1) pat='^'^$1^' '
+if not pat='^('^`{echo $* | sed 's/ /|/g'}^') '
+fils=()
+if(~ $search yes)
+for(i in $S/$sec){
+ if(/bin/test -f $i/INDEX){
+ try=`{grep -i $pat $i/INDEX | sed 's/^[^ ]* //' | sort -u}
+ if(! ~ $#try 0)
+ fils=($fils $i/$try)
+ }
+}
+# bug: should also do following loop if not all pages found
+if(~ $#fils 0) {
+ # nothing in INDEX. try for file of given name
+ for(i) {
+ if(~ $i intro) i=0intro
+ for(n in $sec) {
+ try=`{echo $S/$n/$i | tr A-Z a-z}
+ if (/bin/test -f $try)
+ fils=($fils $try)
+ }
+ }
+ if(~ $#fils 0) {
+ echo 'man: no manual page' >[1=2]
+ exit 'no man'
+ }
+}
+for(i in $fils) {
+ if(! /bin/test -f $i)
+ echo need $i >[1=2]
+ if not {
+ switch($cmd) {
+ case w
+ echo $i
+
+ case t
+ roff t $i
+
+ case p
+ roff t $i | grep -v '^x X html' | proof
+
+ case P
+ roff t $i | page
+
+ case n
+ roff n $i | sed '
+ ${
+ /^$/p
+ }
+ //N
+ /^\n$/D'
+
+ case b
+ x=`{echo $i | sed 's;/sys/man/(.*)/(.*);\1 \2;'}
+ if(~ $x(2) 0intro) x=($x(1) intro)
+ roff n $i | sed '
+ ${
+ /^$/p
+ }
+ //N
+ /^\n$/D' |
+ plumb -i -d edit -a 'action=showdata filename=/man/'$x(2)^'('$x(1)^')'
+ }
+ }
+}
--- /dev/null
+++ b/rc/bin/map
@@ -1,0 +1,103 @@
+#!/bin/rc
+
+rfork en
+
+# F FEATUREs, M map files, A other arguments
+FEATURE=no
+
+if (~ $MAPPROG '')
+ MAPPROG=/bin/aux/mapd
+
+if (~ $MAPDIR '')
+ MAPDIR=/lib/map
+
+F=(); M=(); A=();
+for (i) {
+ switch ($FEATURE) {
+ case no
+ switch ($i) {
+ case -f
+ FEATURE=yes
+ F=($F)
+ case *
+ A=($A $i)
+ }
+ case yes
+ switch ($i) {
+ case -f
+ case -*
+ A=($A $i)
+ FEATURE=no
+ case riv*2
+ F=($F 201 202)
+ case riv*3
+ F=($F 201 202 203)
+ case riv*4
+ F=($F 201 202 203 204)
+ case riv*
+ F=($F 201)
+ case iriv*2
+ F=($F 206 207)
+ case iriv*[34]
+ F=($F 206 207 208)
+ case iriv*
+ F=($F 206)
+ case coast*2 shore*2 lake*2
+ F=($F 102)
+ case coast*3 shore*3 lake*3
+ F=($F 102 103)
+ case coast*4 shore*4 lake*4
+ F=($F 102 103 104)
+ case coast* shore* lake*
+ case ilake*[234] ishore*[234]
+ F=($F 106 107)
+ case ilake* ishore*
+ F=($F 106)
+ case reef*
+ F=($F 108)
+ case canal*2
+ F=($F 210 211)
+ case canal*[34]
+ F=($F 210 211 212)
+ case canal*
+ F=($F 210)
+ case glacier*
+ F=($F 115)
+ case state* province*
+ F=($F 401)
+ case countr*2
+ F=($F 301 302)
+ case countr*[34]
+ F=($F 301 302 303)
+ case countr*
+ F=($F 301)
+ case salt*[234]
+ F=($F 109 110)
+ case salt*
+ F=($F 109)
+ case ice*[234] shel*[234]
+ F=($F 113 114)
+ case ice* shel*
+ F=($F 113)
+ case *
+ echo map: unknown feature $i >[1=2]
+ exits "unknown feature"
+ }
+ }
+}
+
+for (j in $F) {
+ if (test -r $MAPDIR/$j)
+ M=($M $MAPDIR/$j)
+}
+
+if (~ $F ?*) {
+ if (test -r $MAPDIR/101)
+ M=(101 $M)
+ M=(-m $M)
+}
+
+if (~ $MAP '')
+ MAP=world
+
+MAP=$MAP MAPDIR=$MAPDIR $MAPPROG $A $M
--- /dev/null
+++ b/rc/bin/mapdemo
@@ -1,0 +1,83 @@
+#!/bin/rc
+
+fn demo {proj=$1; shift;
+ label=$1; shift;
+ { echo 'o'
+ echo 'ra -8192 -8492 8192 8492'
+ echo 'e'
+ echo 'm -8192 8192'
+ echo t $type
+ echo 'm -8192 -8192'
+ echo t $proj - $label
+ MAP=world MAPDIR=/lib/map map $proj $* -s -d 5
+ }
+ sleep 5
+}
+
+rfork en
+{
+type='Equatorial projections centered on long. 0. Parallels are straight lines.'
+
+demo mercator 'equally spaced straight meridians, conformal, straight compass courses'
+demo sinusoidal 'equally spaced parallels, equal-area, same as bonne(0)'
+demo cylequalarea 'equally spaced straight meridians, equal-area, true scale on Eq' 0
+demo cylindrical 'central projection on tangent cylinder'
+demo rectangular 'equally spaced parallels, equally spaced straight meridians, true scale on Eq' 0
+demo gall 'parallels spaced stereographically on prime meridian, equally spaced straight meridians, true scale on Eq' 0
+demo mollweide '(homalographic) equal-area, hemisphere is a circle'
+demo gilbert 'globe mapped conformally on hemisphere, viewed orthographically'
+
+type='Azimuthal: centered on the North Pole, Parallels are concentric circles, Meridians are equally spaced radial lines'
+
+demo azequidistant 'equally spaced parallels, true distances from pole'
+demo azequalarea 'equal area'
+demo gnomonic 'central projecton on tangent plane, straight great circles'
+demo perspective 'viewed along earth''s axis 2 earth radii from center of earth' 2
+demo orthographic 'viewed from infinity'
+demo stereographic 'conformal, projected from opposite pole'
+demo laue 'radius = tan(2\(mu colatitude ), used in xray crystallography'
+demo fisheye 'fisheye view of stereographic map, index of refraction 2' 2 -o 40.75 74
+demo newyorker 'New Yorker map from viewing pedestal of radius .5' .5 -o 40.75 74
+
+type='Polar conic projections symmetric about the Prime Meridian. Parallels are segments of concentric circles.'
+
+demo conic 'central projection on cone tangent at 40' 40
+demo simpleconic 'equally spaced parallels, true scale on 20 and 50' 20 50
+demo lambert 'conformal, true scale on 20 and 50' 20 50
+demo albers 'equal-area, true scale on 20 and 50' 20 50
+demo bonne 'equally spaced parallels, equal-area, parallel 40 developed from tangent cone' 40
+
+type='Projections with bilateral symmetry about the Prime Meridian and the equator.'
+
+demo polyconic 'parallels developed from tangent cones, equally spaced along Prime Meridian'
+demo aitoff 'equal-area projection of globe onto 2-to-1 ellipse, based on azequalarea'
+demo lagrange 'conformal, maps whole sphere into a circle'
+demo bicentric 'points plotted at true azimuth from two centers on the equator at longitudes +-40, great circles are straight lines' 40
+demo elliptic 'points are plotted at true distance from two centers on the equator at longitudes +-40' 40
+demo globular 'hemisphere is circle, circular meridians and parallels'
+demo vandergrinten 'sphere is circle, meridians as in globular, circular arc parallels resemble mercator'
+
+type='Doubly periodic conformal projections.'
+
+demo guyou 'W and E hemispheres are square'
+demo square 'World is square with Poles at diagonally opposite corners'
+demo tetra 'map on tetrahedron with edge tangent to Prime Meridian at S Pole, unfolded into equilateral triangle'
+demo hex 'world is hexagon centered on N Pole, N and S hemispheres are equilateral
+triangles'
+
+type='Retroazimuthal projections. Directions to center are true.'
+
+demo mecca 'equally spaced vertical meridians' 21.4 -o 90 -39.8
+demo homing 'distances to Mecca are true' 21.4 -o 90 -39.8
+
+type='Miscellaneous projections.'
+
+demo harrison 'oblique perspective from above the North Pole, 2 earth radii from the earth, looking along the Date Line 40 degrees off vertical' 2 40
+demo trapezoidal 'equally spaced parallels, straight meridians equally spaced along parallels, true scale at 20 and 50 on Prime Meridian' 20 50
+demo lune 'conformal, polar cap above Eq is 60-degree lune' 0 60
+
+type='Maps based on the spheroid'
+
+demo sp_mercator 'equally spaced straight meridians, conformal'
+demo sp_albers 'equal-area, true scale on 20 and 50' 20 50
+} | plot
--- /dev/null
+++ b/rc/bin/membername
@@ -1,0 +1,4 @@
+#!/bin/rc
+tr ' ' '\012' <<eof | sed -e 's/[^(]*\(([^)]*)\).*/\1/' | tr '\012' ' '
+$*
+eof
--- /dev/null
+++ b/rc/bin/mousereset
@@ -1,0 +1,3 @@
+#!/bin/rc
+
+echo reset >/dev/mousectl
--- /dev/null
+++ b/rc/bin/nroff
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec troff -N $*
--- /dev/null
+++ b/rc/bin/patch/applied
@@ -1,0 +1,8 @@
+#!/bin/rc
+
+if(~ $#* 0){
+ echo 'usage: patch/applied patch-name...' >[1=2]
+ exit usage
+}
+
+patch/move applied $*
--- /dev/null
+++ b/rc/bin/patch/apply
@@ -1,0 +1,79 @@
+#!/bin/rc
+
+rfork e
+
+if(! ~ $#* 1){
+ echo 'usage: patch/apply patch-name' >[1=2]
+ exit usage
+}
+
+if(! test -d /n/sources/patch){
+ rfork n
+ 9fs sources
+}
+
+if(! test -d /n/sources/patch/$1){
+ echo 'no such patch' /n/sources/patch/$1 >[1=2]
+ exit nopatch
+}
+
+builtin cd /n/sources/patch/$1 || exit nopatch
+if(! patch/okay .){
+ echo 'bad patch: '$status >[1=2]
+ exit badpatch
+}
+
+if(! echo >.tmp || ! rm .tmp){
+ echo no write permission >[1=2]
+ exit 'no write permission'
+}
+
+echo -n merge... >[1=2]
+fn xxx {
+ if(! test -f $1)
+ cp $2 $2.new
+ if not
+ ape/diff3 -m $1 $2.orig $2 >$2.new
+ if(grep -s '^<<<<' $2.new){
+ echo conflicts merging $1';' see `{pwd}^/$2.new >[1=2]
+
+ touch failed
+ }
+}
+rm -f failed
+cat files | sed 's/^/xxx /' | rc
+if(test -f failed){
+ echo exiting without changes >[1=2]
+ exit failed
+}
+
+echo -n backup... >[1=2]
+fn xxx {
+ # echo cp $1 $2.backup
+ cp $1 $2.backup
+}
+cat files | sed 's/^/xxx /' |rc
+
+echo -n copy... >[1=2]
+fn xxx {
+ # echo cp $2.new $1
+ cp $2.new $1 || touch failed
+}
+cat files | sed 's/^/xxx /' | rc
+
+fn xxx {
+ # echo cp $2.backup $1
+ cp $2.backup $1
+}
+
+if(test -f failed){
+ echo copying failed, restoring backups >[1=2]
+ cat files | sed 's/^/xxx /' | rc
+ exit failed
+}
+
+echo >[1=2]
+
+echo to update sources: >[1=2]
+cat files | awk '{print " update " $1 }' >[1=2]
+
--- /dev/null
+++ b/rc/bin/patch/create
@@ -1,0 +1,85 @@
+#!/bin/rc
+rfork e
+
+fn xchmod {
+ chmod $* >[2]/dev/null
+}
+
+if(~ $#* 0 1 2){
+ echo 'usage: patch/create name email file... [< description]' >[1=2]
+ exit usage
+}
+
+if(! echo $1 | grep -s '^[a-z_0-9.\-]+$'){
+ echo 'bad name: [a-z0-9._\-]+ only' >[1=2]
+ exit usage
+}
+if(! echo $2 | grep -s '^(-|[A-Za-z0-9.\-+]+@[A-Za-z0-9.\-+]+)$'){
+ echo 'bad email: [a-z0-9.-+] only; use ''-'' to not leave an email address.' >[1=2]
+ exit usage
+}
+
+if(! test -d /n/sources/patch){
+ rfork n
+ 9fs sources
+}
+
+patch=$1
+email=$2
+shift
+shift
+d=/n/sources/patch/$patch
+if(! mkdir $d){
+ echo mkdir $d failed >[1=2]
+ exit mkdir
+}
+if(! ~ $email -){
+ echo $email >$d/email
+}
+
+xchmod o-w $d
+>$d/readme
+>$d/files
+>$d/notes
+for(i in $*){
+ i=`{cleanname -d `{pwd} $i}
+ if(! test -f $i){
+ echo error: cannot find $i >[1=2]
+ rm -rf $d
+ exit oops
+ }
+ short=`{basename $i}
+ uniq=$short
+ n=0
+ while(test -f $d/$uniq){
+ uniq=$short.$n
+ n=`{echo 1+$n | hoc}
+ }
+ cp $i $d/$uniq
+ if(test -f /n/sources/plan9/$i){
+ if(cmp -s /n/sources/plan9/$i $i)
+ echo warning: new file $i does not differ from sources >[1=2]
+ cp /n/sources/plan9/$i $d/$uniq.orig
+ }
+ if not
+ echo warning: new file $i not on sources >[1=2]
+ echo $i $uniq >>$d/files
+}
+@{builtin cd $d && xchmod ug+rw * && xchmod a+r *}
+
+if(~ `{cat /proc/$pid/fd | awk 'NR==2{print $NF}'} */dev/cons && test -w /dev/consctl){
+ >/dev/consctl {
+ echo holdon
+ cat >$d/readme
+ }
+}
+if not
+ cat >$d/readme
+
+if(! test -s $d/readme){
+ echo 'no description given; aborting' >[1=2]
+ rm -rf $d
+ exit oops
+}
+
+echo $d
--- /dev/null
+++ b/rc/bin/patch/diff
@@ -1,0 +1,45 @@
+#!/bin/rc
+# patch/diff [-w] patch-name
+rfork e
+fn usage {
+ echo 'usage: patch/diff [-bmnwz] patch-name' >[1=2]
+ exit usage
+}
+
+dopts=(-c)
+while (! ~ $#* 0 && ~ $1 -*) {
+ switch ($1) {
+ case -[bmnw]
+ dopts=($dopts $1)
+ case -z
+ dopts=()
+ case *
+ usage
+ }
+ shift
+}
+if(! ~ $#* 1)
+ usage
+
+if(! test -d /n/sources/patch){
+ rfork n
+ 9fs sources
+}
+
+if(! test -d /n/sources/patch/$1){
+ echo 'no such patch' /n/sources/patch/$1 >[1=2]
+ exit nopatch
+}
+
+builtin cd /n/sources/patch/$1 || exit nopatch
+if(! patch/okay .){
+ echo 'bad patch: '$status >[1=2]
+ exit badpatch
+}
+
+d=/n/sources/patch/$1
+fn xxx {
+ echo $1
+ diff $dopts $2.orig $d/$2 | sed 's/^/ /'
+}
+cat files | sed 's/^/xxx /' | rc
--- /dev/null
+++ b/rc/bin/patch/list
@@ -1,0 +1,54 @@
+#!/bin/rc
+
+rfork e
+if(! test -d /n/sources/patch){
+ rfork n
+ 9fs sources
+}
+
+pref=''
+builtin cd /n/sources/patch || {
+ echo 'can''t cd /n/sources/patch' >[2=1]
+ exit no-sources
+}
+
+if(~ $1 applied saved sorry maybe){
+ pref=$1^'/'
+ shift
+}
+if(~ $#* 0)
+ *=(`{
+ if(~ $pref *?*)
+ builtin cd $pref
+ ls -t | grep -v '^(applied|saved|sorry|maybe)$'
+ })
+
+trunc=(sed 5q)
+if(~ $#* 1)
+ trunc=cat
+
+{
+for(i in $*){
+ i=$pref^$i
+ if(test -f $i/origls)
+ cat $i/origls | awk '{$NF="'$i'"; print}'
+ if not
+ ls -ld $i
+ if(patch/okay $i){
+ if(test -r $i/email)
+ echo from `{cat $i/email}
+ cat $i/files | awk '{print " " $1}'
+ cat $i/readme | sed 's/^/ /' | $trunc
+ if(test -f $i/notes){
+ echo
+ cat $i/notes
+ }
+ }
+ if not
+ echo ' 'bad patch: $status >[2=1]
+ echo
+}
+} >/tmp/patchtmp.$pid
+
+cat /tmp/patchtmp.$pid
+rm -f /tmp/patchtmp.$pid
--- /dev/null
+++ b/rc/bin/patch/move
@@ -1,0 +1,31 @@
+#!/bin/rc
+# patch/move target patch-tree... - move patch tree(s) to target dir
+rfork e
+pats=/n/sources/patch
+if(~ $#* 0 1){
+ echo 'usage: patch/move dst patch-name...' >[1=2]
+ exit usage
+}
+
+if(! test -d $pats){
+ rfork n
+ 9fs sources
+}
+cd $pats
+
+dst=$1
+shift
+for(src){
+ patbase = `{basename $src}
+ patdest = $dst/$patbase
+ if (~ $dst $src $patbase)
+ echo $0: skipping $src >[1=2]
+ if not if(! test -d $src)
+ echo $0: no such patch $pats/$src >[1=2]
+ if not if(test -d $patdest)
+ echo $0: already have $pats/$patdest >[1=2]
+ if not
+ ls -ldp $src >$src/origls &&
+ mkdir $patdest && dircp $src $patdest && rm -rf $src &&
+ test -s $patdest/email && patch/notify $patdest
+}
--- /dev/null
+++ b/rc/bin/patch/note
@@ -1,0 +1,35 @@
+#!/bin/rc
+
+rfork e
+if(! ~ $#* 1){
+ echo 'usage: patch/note patch-name' >[1=2]
+ exit usage
+}
+
+if(! test -d /n/sources/patch){
+ rfork n
+ 9fs sources
+}
+
+if(! test -d /n/sources/patch/$1){
+ echo 'no such patch' /n/sources/patch/$1 >[1=2]
+ exit nopatch
+}
+
+builtin cd /n/sources/patch/$1 || exit nopatch
+if(! patch/okay .){
+ echo 'bad patch: '$status >[1=2]
+ exit badpatch
+}
+
+if(~ `{cat /proc/$pid/fd | awk 'NR==2{print $NF}'} */dev/cons && ~ `{ls -l /dev/consctl | awk '{print $1}'} *w*){
+ >/dev/consctl {
+ echo holdon
+ {echo `{date} `{cat /dev/user}
+ cat |sed 's/^/ /'; echo } >>notes
+ }
+}
+if not
+ {echo `{date} `{cat /dev/user}
+ cat |sed 's/^/ /'; echo } >>notes
+
--- /dev/null
+++ b/rc/bin/patch/notify
@@ -1,0 +1,9 @@
+#!/bin/rc
+# patch/notify
+rfork e
+for(i)
+ # don't flood sys when merely shuffling patches around
+ if (~ $i applied/* saved/* sorry/*) {
+ patch/list $i | mail -s 'patch/list '^$i sys \
+ `{cat /n/sources/patch/$i/email}
+ }
--- /dev/null
+++ b/rc/bin/patch/okay
@@ -1,0 +1,14 @@
+#!/bin/rc
+
+rfork e
+if(! ~ $#* 1){
+ echo usage: patch/okay dir >[1=2]
+ exit usage
+}
+
+i=$1
+if(! test -s $i/files || ! test -s $i/readme)
+ exit 'missing files'
+if(grep -v '^/[_a-zA-Z0-9.\-+/:]+ [_a-zA-Z0-9.\-+:]+$' $i/files)
+ exit 'bad file list'
+exit 0
--- /dev/null
+++ b/rc/bin/patch/remove
@@ -1,0 +1,19 @@
+#!/bin/rc
+
+rfork e
+if(~ $#* 0){
+ echo 'usage: patch/remove patch-name...' >[1=2]
+ exit usage
+}
+
+if(! test -d /n/sources/patch){
+ rfork n
+ 9fs sources
+}
+
+for(i){
+ if(! test -d /n/sources/patch/$i)
+ echo 'no such patch' /n/sources/patch/$i >[1=2]
+ if not
+ rm -rf /n/sources/patch/$i
+}
--- /dev/null
+++ b/rc/bin/patch/save
@@ -1,0 +1,8 @@
+#!/bin/rc
+
+if(~ $#* 0){
+ echo 'usage: patch/save patch-name...' >[1=2]
+ exit usage
+}
+
+patch/move saved $*
--- /dev/null
+++ b/rc/bin/patch/sorry
@@ -1,0 +1,8 @@
+#!/bin/rc
+
+if(~ $#* 0){
+ echo 'usage: patch/sorry patch-name...' >[1=2]
+ exit usage
+}
+
+patch/move sorry $*
--- /dev/null
+++ b/rc/bin/patch/undo
@@ -1,0 +1,35 @@
+#!/bin/rc
+
+rfork e
+if(! ~ $#* 1){
+ echo 'usage: patch/undo patch-name' >[1=2]
+ exit usage
+}
+
+if(! test -d /n/sources/patch){
+ rfork n
+ 9fs sources
+}
+
+if(! test -d /n/sources/patch/$1){
+ echo 'no such patch' /n/sources/patch/$1 >[1=2]
+ exit nopatch
+}
+
+d=$1
+builtin cd /n/sources/patch/$1 || exit nopatch
+if(! patch/okay .){
+ echo 'bad patch: '$status >[1=2]
+ exit badpatch
+}
+
+fn xxx {
+ if(cmp $2.new $1){
+ echo cp /n/sources/patch/$d/$2.backup $1
+ cp $2.backup $1
+ }
+ if not
+ echo $1 has changed since patch was applied! >[2=1]
+}
+cat files | sed 's/^/xxx /' |rc
+
--- /dev/null
+++ b/rc/bin/pc/bootfloppy
@@ -1,0 +1,22 @@
+#!/bin/rc
+
+if(~ $#* 0 1) {
+ echo 'usage: bootfloppy /dev/fd0disk plan9.ini [files...]'>[1=2]
+ exit usage
+}
+
+if(! test -f $2) {
+ echo $2 does not exist >[1=2]
+ exit noplan9.ini
+}
+
+disk=$1
+ini=$2
+shift
+shift
+
+mkdir /tmp/bootfloppy.$pid
+cp $ini /tmp/bootfloppy.$pid/plan9.ini
+dd -bs 512 -count 1 < /dev/zero >/tmp/bootfloppy.$pid/plan9.nvr
+disk/format -b /386/pbs -f -d $disk /386/9load /tmp/bootfloppy.$pid/* $*
+rm -rf /tmp/bootfloppy.$pid
--- /dev/null
+++ b/rc/bin/pc/bootplan9
@@ -1,0 +1,72 @@
+#!/bin/rc
+
+rfork e
+
+. /rc/bin/pc/defs
+
+if(! ~ $#* 1) {
+ echo 'usage: bootplan9 /dev/sdC0' >[1=2]
+ echo 'sets active the plan 9 partition on the named disk.' >[1=2]
+ exit usage
+}
+
+disk=$1
+
+fn x {
+ if(! test -f $disk/$1) {
+ echo 'could not find '$disk/$1
+ exit disk
+ }
+}
+
+x plan9
+x data
+x ctl
+
+diskbase=`{basename `{cleanname $disk}}
+
+first=`{ls -p '#S' | sed 1q}
+if(! ~ $first $diskbase) {
+ echo 'warning: The plan 9 partition is not on the boot disk,' >[1=2]
+ echo 'so making it the active partition will have no effect.' >[1=2]
+}
+
+p9offset=`{disk/fdisk -p $disk/data |grep '^part plan9 ' | awk '{print $4}'}
+if(! ~ $#p9offset 1) {
+ echo 'could not find plan 9 partition.' >[1=2]
+ echo 'cannot happen' >[1=2]
+ exit bad
+}
+
+if(test $p9offset -gt 4128705) { # 65536 * 63
+ echo >[1=2]
+ echo 'Your Plan 9 partition is more than 2GB into your disk,' >[1=2]
+ echo 'and the master boot records used by most operating systems' >[1=2]
+ echo 'cannot access it (and thus cannot boot it).' >[1=2]
+ echo >[1=2]
+ echo 'Would you like to install a master boot record' >[1=2]
+ echo 'that will be able to access partitions more than 2GB into the disk?' >[1=2]
+ echo >[1=2]
+ prompt 'Install a new mbr' y n
+ switch($rd) {
+ case n
+ echo >[1=2]
+ echo 'Not setting Plan 9 partition active, then.' >[1=2]
+ echo >[1=2]
+ exit bad
+ case y
+ disk/mbr -m /386/mbr $disk/data
+ }
+}
+
+p9part=`{disk/fdisk $disk/data >[2]/dev/null </dev/null |
+ grep PLAN9 | sed 1q | sed 's/ *(p.) .*/\1/'}
+if(~ $#p9part 1) {
+ { echo 'A '^$p9part; echo w } | disk/fdisk $disk/data >[2]/dev/null >/dev/null
+}
+if not {
+ echo 'Could not find Plan 9 partition.'
+ exit notdone
+}
+
+exit
--- /dev/null
+++ b/rc/bin/pc/bootwin9x
@@ -1,0 +1,115 @@
+#!/bin/rc
+
+dosdisk=`{ls /dev/sd??/dos >[2]/dev/null | sed 1q | sed 's!.*/(.*)/dos!\1!'}
+if(~ $#dosdisk 0 || ! c: || ! test -f /n/c:/autoexec.bat || ! test -f /n/c:/config.sys) {
+ echo 'Could not find autoexec.bat or config.sys on the first FAT disk.' >[1=2]
+ exit
+}
+
+for (i in autoexec config msdos)
+ if(test -f /n/c:/$i.p9) {
+ echo 'A Plan 9 backup already exists; will not edit system files again.' >[1=2]
+ exit
+ }
+
+for (i in autoexec.bat config.sys msdos.sys)
+ if(! cp /n/c:/$i /n/c:/^`{echo $i | sed 's/\.(bat|sys)$/.p9/'}) {
+ echo 'Could not back up '^$i^'; will not continue.' >[1=2]
+ exit
+ }
+
+if(! test -d /n/c:/plan9 && ! mkdir /n/c:/plan9) {
+ echo 'Could not create directory /n/c:/plan9.' >[1=2]
+ exit
+}
+
+if(! cp /386/^(9load ld.com) /386/9pcdisk /n/c:/plan9) {
+ echo 'Could not copy Plan 9 boot files into /n/c:/plan9.' >[1=2]
+ exit
+}
+
+chmod +w /n/c:/autoexec.bat /n/c:/config.sys /n/c:/msdos.sys
+
+if(grep -si 'Plan ?9' /n/c:/config.sys || grep -si 'Plan ?9' /n/c:/autoexec.bat) {
+ echo 'Plan 9 entries already in config.sys or autoexec.bat.' >[1=2]
+ echo 'Not changing them; refer to Plan 9 install documentation' >[1=2]
+ echo 'to configure manually.' >[1=2]
+ exit
+}
+
+if(! grep -si '\[menu\]' /n/c:/config.sys) {
+ {
+ echo 1
+ echo i
+ echo '[menu] '
+ echo 'menuitem=windows, Windows '
+ echo 'menudefault=windows '
+ echo ' '
+ echo '[common] '
+ echo ' '
+ echo '[windows] '
+ echo .
+ echo w
+ echo q
+ } | ed /n/c:/config.sys >/dev/null >[2]/dev/null
+}
+
+{
+ echo 1
+ echo '/\[[Mm][Ee][Nn][Uu]\]'
+ echo '?^[Mm][Ee][Nn][Uu][Ii][Tt][Ee][Mm]='
+ echo a
+ echo 'menuitem=plan9, Plan 9 from Bell Labs '
+ echo .
+ echo '$'
+ echo a
+ echo ' '
+ echo '[plan9] '
+ echo ' '
+ echo .
+ echo w
+ echo q
+} | ed /n/c:/config.sys >/dev/null >[2]/dev/null
+
+{
+ echo 1
+ echo i
+ echo '@echo off '
+ echo 'if %config%==plan9 goto plan9 '
+ echo 'goto notplan9 '
+ echo ':plan9 '
+ echo 'plan9\ld '^$dosdisk^'!dos!plan9/9load '
+ echo ':notplan9 '
+ echo .
+ echo w
+ echo q
+} | ed /n/c:/autoexec.bat >/dev/null >[2]/dev/null
+
+fn zeroopt {
+ if(grep -s '^'^$1^'=1' /n/c:/msdos.sys) {
+ {
+ echo '/^'^$1^'=1/s/=1/=0/'
+ echo w
+ echo q
+ } | ed /n/c:/msdos.sys >/dev/null >[2]/dev/null
+ }
+ if not if (grep -s '^'^$1^'=0' /n/c:/msdos.sys)
+ ;
+ if not {
+ {
+ echo 1
+ echo i
+ echo '[Options] '
+ echo 'Logo=0 '
+ echo .
+ echo w
+ echo q
+ } | ed /n/c:/msdos.sys >/dev/null >[2]/dev/null
+ }
+}
+
+if(grep -si '^\[paths\]' /n/c:/msdos.sys){ # Windows 9x rather than DOS
+ zeroopt Logo
+}
+
+exit
--- /dev/null
+++ b/rc/bin/pc/bootwinnt
@@ -1,0 +1,53 @@
+#!/bin/rc
+
+disk=`{ls /dev/sd??/plan9 >[2]/dev/null | sed 1q | sed 's!.*/(.*)/plan9!\1!'}
+if(! ~ $#disk 1) {
+ echo 'No plan 9 disk found' >[1=2]
+ exit
+}
+
+if(! c: || ! test -f /n/c:/boot.ini) {
+ echo 'Could not find NT''s boot.ini on the first FAT disk.' >[1=2]
+ exit
+}
+
+if(test -f /n/c:/boot.p9) {
+ echo 'A Plan 9 backup already exists; will not edit boot.ini again.' >[1=2]
+ exit
+}
+
+if(! cp /n/c:/boot.ini /n/c:/boot.p9) {
+ echo 'Could not back up boot.ini; will not continue.' >[1=2]
+ exit
+}
+
+chmod +w /n/c:/boot.ini
+
+if(! grep -si '\[operating systems\]' /n/c:/boot.ini) {
+ echo 'Could not parse boot.ini.' >[1=2]
+ exit
+}
+
+if(grep -si 'Plan 9' /n/c:/boot.ini) {
+ p9file=`{grep 'Plan 9' /n/c:/boot.ini | sed 1q | sed 's/=.*//'}
+ if(! ~ $p9file [Cc]:'\'*) {
+ echo 'Unexpected Plan 9 entry in boot.ini already; not continuing.' >[1=2]
+ exit
+ }
+}
+
+if not {
+ p9file='c:\bootsect.p9'
+ echo 'c:\bootsect.p9 = "Plan 9 from Bell Labs" ' >>/n/c:/boot.ini
+}
+
+p9file=/n/^`{echo $p9file | sed 's!\\!/!g'}
+
+
+if(dd -if /dev/$disk/plan9 -bs 512 -count 1 -of $p9file >/dev/null >[2]/dev/null) {
+ echo 'Plan 9 added to Windows NT boot menu.' >[1=2]
+ exit
+}
+
+echo 'Error copying Plan 9 boot sector to file.'
+exit
--- /dev/null
+++ b/rc/bin/pc/defs
@@ -1,0 +1,72 @@
+nl='
+'
+tab=' '
+
+fn prompt {
+ def=()
+ what=()
+ if(~ $1 -d && ! ~ $#* 1){
+ def=$2
+ shift
+ shift
+ }
+
+ optstr=()
+ if(~ $1 -w && ! ~ $#* 1){
+ optstr=$2
+ shift
+ shift
+ }
+
+ pr=$1
+ shift
+
+ opts=($*)
+ if(~ $#opts 0) {
+ suf=' '
+ }
+ if not if(! ~ $#optstr 0) {
+ if(~ $optstr '')
+ suf=' '
+ if not {
+ pr=$pr^' ('^$"optstr^')'
+ suf=''
+ }
+ }
+ if not {
+ pr=$pr^' ('^$1
+ shift
+ for(i)
+ pr=$pr^', '^$i
+ pr=$pr^')'
+ suf=''
+ }
+
+ if(~ $#def 1)
+ pr=$pr^$suf^'['^$def^']'
+ pr=$pr^': '
+
+
+ okay=no
+ while(~ $okay no) {
+# whatis opts
+ echo -n $pr >[1=2]
+ ifs='' {rd=`{read}}
+ if(~ $#rd 0)
+ exit notdone
+ rd=`{echo $rd}
+ if(~ $#rd 0 || ~ $rd '')
+ rd=$def
+
+ switch($#opts){
+ case 0
+ if(! ~ $rd '')
+ okay=yes
+ case *
+ if(~ $rd $opts)
+ okay=yes
+ }
+ }
+ echo -n $rd >/env/rd # just in case
+}
+
--- /dev/null
+++ b/rc/bin/pc/isfat
@@ -1,0 +1,22 @@
+#!/bin/rc
+
+rfork e
+
+# 0000000 eb 3c 90 P l a n 9 . 0 0 00 02 04 02 00
+# 0000010 02 00 02 02 P f8 14 00 ? 00 ff 00 ~ 04 } 00
+# 0000020 02 P 00 00 80 00 ) a8 04 } 00 C Y L I N
+# 0000030 D R I C A L F A T 1 6 fa 8c
+
+if(! ~ $#* 1) {
+ echo 'usage: isfat /dev/sdC0/part' >[1=2]
+ exit usage
+}
+
+arg=$1
+fn fat {
+ cmp -s <{dd -if $arg -bs 1 -count 3 -skip $1 >[2]/dev/null} <{echo -n FAT}
+}
+
+fat 54 || fat 82
+exit $status
+
--- /dev/null
+++ b/rc/bin/pc/personalize
@@ -1,0 +1,7 @@
+#!/bin/rc
+
+switch($#*){
+case 1
+ user=$1
+}
+disk/mkfs -s /n/emelie /sys/lib/sysconfig/proto/usrproto
--- /dev/null
+++ b/rc/bin/pc/setup.9fat
@@ -1,0 +1,33 @@
+#!/bin/rc
+
+rfork e
+if(! ~ $#* 2) {
+ echo 'usage: setup.9fat /dev/sdC0/9fat plan9.ini' >[1=2]
+ exit usage
+}
+
+. /rc/bin/pc/defs
+fat=$1
+ini=$2
+if(! test -f $fat) {
+ echo fat partition not found >[1=2]
+ exit fat
+}
+if(! test -f $ini) {
+ echo plan9.ini not found >[1=2]
+ exit ini
+}
+
+if(pc/isfat $fat) {
+ echo 'Already a FAT partition in '^$fat^'; ream it?'
+ prompt 'ream 9fat' y n
+ switch($rd) {
+ case n
+ exit
+ }
+}
+
+disk/format -r 2 -d -b /386/pbs $fat /386/9load /386/9pcdisk
+mount -c /srv/dos /n/9fat $fat
+cp $ini /n/9fat/plan9.ini
+unmount /n/9fat
--- /dev/null
+++ b/rc/bin/pc/setup.disk
@@ -1,0 +1,37 @@
+#!/bin/rc
+
+rfork e
+
+if(! ~ $#* 2) {
+ echo 'usage: setup.disk /dev/sdC0 plan9.ini' >[1=2]
+ exit usage
+}
+
+disk=$1
+ini=$2
+if(! test -d $disk) {
+ echo disk directory not found >[1=2]
+ exit fat
+}
+if(! test -f $ini) {
+ echo plan9.ini not found >[1=2]
+ exit ini
+}
+
+
+disk/fdisk -wa $disk/data
+if(! test -f $disk/plan9) {
+ echo could not create plan 9 partition >[1=2]
+ exit noplan9
+}
+
+disk/prep -cwa $disk/plan9
+if(! test -f $disk/fs) {
+ echo did not create fs partition '(weird)' >[1=2]
+ exit nofs
+}
+
+disk/kfs -rb4096 -f $disk/fs
+pc/setup.9fat $disk/9fat $ini
+pc/update
+pc/personalize
--- /dev/null
+++ b/rc/bin/pc/update
@@ -1,0 +1,20 @@
+#!/bin/rc
+
+if(~ $#fileserver 0) {
+ echo set '$fileserver' >[1=2]
+ exit no
+}
+if(~ $fileserver kfs) {
+ echo pc/update shouldn''''t be run from kfs >[1=2]
+ echo 'run:' >[1=2]
+ echo ' fileserver=network-server pc/update' >[1=2]
+ exit no
+}
+flag e +
+echo updating files
+9fs $fileserver
+disk/mkfs -s /n/$fileserver /n/$fileserver/sys/lib/sysconfig/proto/portproto
+9fat:
+cp /n/$fileserver/386/9pcdisk /n/9fat/9pcdisk
+cp /n/$fileserver/386/9load /n/9fat/9load
+unmount /n/9fat
--- /dev/null
+++ b/rc/bin/pci
@@ -1,0 +1,95 @@
+#!/bin/rc
+# pci [-bv] - dump pci configuration
+rfork e
+fn verbose {
+ if (! test -f /lib/pci)
+ echo $0: no /lib/pci >[1=2]
+ awk '
+
+ function lower(s) {
+ gsub(/A/, "a", s)
+ gsub(/B/, "b", s)
+ gsub(/C/, "c", s)
+ gsub(/D/, "d", s)
+ gsub(/E/, "e", s)
+ gsub(/F/, "f", s)
+ return s
+ }
+ BEGIN{
+ file="/lib/pci"
+ FS="\t"
+ while(getline <file > 0){
+ if(/^;/) continue
+ if(/^[0-9a-fA-F]/){
+ vid=lower($1)
+ vendor[vid] = $2
+ }
+ if(/^ [0-9a-fA-F]/){
+ did=lower($2)
+ id[vid "/" did] = $3
+ }
+ }
+ FS = " "
+ }
+
+ {
+ print $0
+ vid = $4
+ sub(/\/.*/, "", vid)
+ if(vid in vendor){
+ s = vendor[vid]
+ if($4 in id)
+ s = s " " id[$4]
+ print "\t" s
+ }
+ }
+'
+}
+fn usage {
+ echo usage: $1 '[-bv]' >[1=2]
+ exit usage
+}
+
+filter=cat
+bridges=yes
+done=0
+while (~ $done 0 && ! ~ $#* 0 && ~ $1 -*) {
+ if (~ $1 -*b*)
+ bridges=no
+ if (~ $1 -*v*)
+ filter=verbose
+ switch ($1) {
+ case --
+ done = 1 # no break in rc, alas
+ case -*[~bv]*
+ usage $0
+ }
+ shift
+}
+if (! ~ $#* 0)
+ usage $0
+
+builtin cd '#$/pci' && grep . *ctl | {
+ if (~ $bridges no)
+ sed /:06/d
+ if not
+ cat
+ } |
+ sed '
+ s/ctl:/: /
+ t noop
+: noop
+ s/: 01/: disk 01/
+ s/: 02/: net 02/
+ s/: 03/: vid 03/
+ s/: 04/: aud 04/
+ s/: 05/: mem 05/
+ s/: 06/: brg 06/
+ s/: 07/: ser 07/
+ s/: 0c\.03/: usb 0c.03/
+ s/: 0c\.05/: smb 0c.05/
+ s/: 0d/: rad 0d/
+ s/: 10/: cryp 10/
+ t
+ s/ / --- /
+' | $filter
--- /dev/null
+++ b/rc/bin/pdf2ps
@@ -1,0 +1,53 @@
+#!/bin/rc
+# pdf2ps [gs-options] [input.pdf] [output.ps] - generate PS from PDF
+rfork e
+
+fn cleanup { }
+fn usage {
+ echo 'usage: pdf2ps [gs-options] [input.pdf] [output.ps]' >[1=2]
+ exit usage
+}
+
+lang=(-'dLanguageLevel=2')
+opt=()
+while(! ~ $#* 0 && ~ $1 -* && ! ~ $1 - --){
+ if(~ $1 '-dLanguageLevel='*)
+ lang=()
+ opt=($opt $1)
+ shift
+}
+if(~ $1 --)
+ shift
+
+switch($#*){
+case 0
+ fin=-
+ fout=-
+case 1
+ fin=$1
+ fout=-
+case 2
+ fin=$1
+ fout=$2
+case *
+ usage
+}
+
+if(~ $fin -){
+ # fin=/tmp/pdf2ps.$pid.^`{date -n}
+ # fn cleanup { rm -f $fin }
+ # cat >$tmp
+ fin=/fd/0
+}
+if(~ $fout -)
+ fout=/fd/1
+
+# Doing an inital `save' helps keep fonts from being flushed between
+# pages. We have to include the options twice because -I only takes
+# effect if it appears before other options.
+
+gs $opt -dSAFER -dNOPAUSE -dBATCH -q -s'DEVICE=pswrite' \
+ $opt $lang \
+ -s'OutputFile='$fout -c save pop -f $fin
+
+cleanup
--- /dev/null
+++ b/rc/bin/printfont
@@ -1,0 +1,105 @@
+#!/bin/rc
+# Formatted dump of encoded characters in one or more PostScript fonts.
+# Arguments should be PostScript font names or the word all, which dumps
+# all ROM and disk based fonts.
+#
+
+POSTLIB=/sys/lib/postscript/prologues
+PROLOGUE=$POSTLIB/printfont.ps
+
+OPTIONS=''
+COPYFILE=''
+MODE=portrait
+FONTENCODING=Default
+
+NONCONFORMING='%!PS'
+ENDPROLOG='%%EndProlog'
+BEGINSETUP='%%BeginSetup'
+ENDSETUP='%%EndSetup'
+TRAILER='%%Trailer'
+
+SETUP=setup
+
+while (! ~ $#* 0 && ~ $1 -*) {
+ switch ($1) {
+ case -a; shift; OPTIONS=$OPTIONS' /axescount $1 def'
+ case -a*; OPTIONS=$OPTIONS' /axescount '`{echo $1 | sed s/-a//}' def'
+
+ case -b; shift; OPTIONS=$OPTIONS' /radix '$1' def'
+ case -b*; OPTIONS=$OPTIONS' /radix '`{echo $1 | sed s/-b//}' def'
+
+ case -c; shift; OPTIONS=$OPTIONS' /#copies '$1' store'
+ case -c*; OPTIONS=$OPTIONS' /#copies '`{echo $1 | sed s/-c//}' store'
+
+ case -f; shift; OPTIONS=$OPTIONS' /labelfont /'$1' def'
+ case -f*; OPTIONS=$OPTIONS' /labelfont /'`{echo $1 | sed s/-f//}' def'
+
+ case -g; shift; OPTIONS=$OPTIONS' /graynotdef '$1' def'
+ case -g*; OPTIONS=$OPTIONS' /graynotdef '`{echo $1 | sed s/-g//}' def'
+
+ case -p; shift; MODE=$1
+ case -p*; MODE=`{echo $1 | sed s/-p//}
+
+ case -q; OPTIONS=$OPTIONS' /longnames false def /charwidth false def'
+
+ case -m; shift; OPTIONS=$OPTIONS' /magnification '$1' def'
+ case -m*; OPTIONS=$OPTIONS' /magnification '`{echo $1 | sed s/-m//}' def'
+
+ case -v; OPTIONS=$OPTIONS' /longnames true def /charwidth true def'
+
+ case -w; shift; OPTIONS=$OPTIONS' /linewidth '$1' def'
+ case -w*; OPTIONS=$OPTIONS' /linewidth '`{echo $1 | sed s/-w//}' def'
+
+ case -x; shift; OPTIONS=$OPTIONS' /xoffset '$1' def'
+ case -x*; OPTIONS=$OPTIONS' /xoffset '`{echo $1 | sed s/-x//}' def'
+
+ case -y; shift; OPTIONS=$OPTIONS' /yoffset '$1' def'
+ case -y*; OPTIONS=$OPTIONS' /yoffset '`{echo $1 | sed s/-y//}' def'
+
+ case -z; shift; OPTIONS=$OPTIONS' /zerocell '$1' def'
+ case -z*; OPTIONS=$OPTIONS' /zerocell '`{echo $1 | sed s/-z//}' def'
+
+ case -C; shift; COPYFILE=$COPYFILE' '$1
+ case -C*; COPYFILE=$COPYFILE' '`{echo $1 | sed s/-C//}
+
+ case -E; shift; FONTENCODING=$1
+ case -E*; FONTENCODING=`{echo $1 | sed s/-E//}
+
+ case -L; shift; PROLOGUE=$1
+ case -L*; PROLOGUE=`{echo $1 | sed s/-L//}
+
+ case -*; echo $0:' illegal option '$1 >[1=2]; exit 1
+ }
+ shift
+}
+
+switch ($MODE) {
+case l*; OPTIONS=$OPTIONS' /landscape true def'
+case *; OPTIONS=$OPTIONS' /landscape false def'
+}
+
+echo $NONCONFORMING
+cat $PROLOGUE
+echo $ENDPROLOG
+echo $BEGINSETUP
+if (~ $#COPYFILE 0 || ~ $COPYFILE '') COPYFILE=/dev/null
+cat $COPYFILE
+echo $OPTIONS
+
+switch ($FONTENCODING) {
+case /*; cat $FONTENCODING
+case ?*; cat $POSTLIB^/$FONTENCODING^.enc >[2]/dev/null
+}
+
+echo $SETUP
+echo $ENDSETUP
+
+for (i) {
+ switch ($i) {
+ case all; echo AllFonts
+ case /*; echo $i' PrintFont'
+ case ?*; echo /$i' PrintFont'
+ }
+}
+
+echo $TRAILER
--- /dev/null
+++ b/rc/bin/ps2gif
@@ -1,0 +1,2 @@
+#!/bin/rc
+cat $1|/bin/gs -dNOPAUSE -dQUIET '-sOUTPUTFILE='/fd/1 '-sDEVICE=inferno' - quit.ps| crop | togif
--- /dev/null
+++ b/rc/bin/ps2pdf
@@ -1,0 +1,43 @@
+#!/bin/rc
+# ps2pdf - convert PostScript to PDF
+rfork e
+
+fn usage {
+ echo 'usage: ps2pdf [gs-options] [input.ps [output.pdf]]' >[1=2]
+ exit usage
+}
+
+# gs's pdfwrite sometimes emits bad pdf at level 1.2,
+# but 1.4 seems to work fine.
+compat=(-'dCompatibilityLevel=1.2')
+opt=()
+while(! ~ $#* 0 && ~ $1 -* && ! ~ $1 - --){
+ if(~ $1 '-dCompatibilityLevel='*)
+ compat=()
+ opt=($opt $1)
+ shift
+}
+if(~ $1 --)
+ shift
+
+switch($#*){
+case 0
+ fin='-'
+ fout='-'
+case 1
+ fin=$1
+ fout='-'
+case 2
+ fin=$1
+ fout=$2
+case *
+ usage
+}
+
+# We have to include the options twice because -I only takes effect
+# if it appears before other options.
+
+gscmd=( gs $opt -dSAFER -dNOPAUSE -dBATCH -q -s'DEVICE=pdfwrite' \
+ $opt $compat \
+ -s'OutputFile='$fout -c .setpdfwrite -f $fin)
+exec $gscmd
--- /dev/null
+++ b/rc/bin/psfax
@@ -1,0 +1,90 @@
+#!/bin/rc
+view=no
+stdin=no
+
+switch($1){
+case -v
+ view=yes
+ shift
+}
+
+switch($#*){
+case 0 1
+ echo usage: $0 telephone-number recipient [files]
+ exit 0
+case 2
+ stdin=yes
+}
+
+telno=$1
+shift
+
+recip=$1
+shift
+
+script=/tmp/fax.$pid
+header=/tmp/faxh.$pid
+user=`{cat /dev/user}
+tmp=/tmp/page.$pid
+tmpin=/tmp/page.in.$pid
+tel=`{grep '\) '$user /lib/tel}
+myname=`{echo $tel | sed 's/ \(.*//'}
+ext=`{echo $tel | sed 's/.*\) [^ ]* [^ ]* ([^ ]*).*/\1/'}
+
+fn sigint{
+ #rm -f $tmp.* $tmpin.* $script $header $header.*
+ exit interrupt
+
+}
+
+# gs insists on reading its standard input, so we read quit.ps to cut it off.
+switch($stdin){
+case yes
+ cat > $tmpin
+ gs -dSAFER '-sDEVICE=dfaxlow' '-sOUTPUTFILE='$tmp'.%.3d' -dNOPAUSE -dQUIET $tmpin quit.ps
+case *
+ gs -dSAFER '-sDEVICE=dfaxlow' '-sOUTPUTFILE='$tmp'.%.3d' -dNOPAUSE -dQUIET $* quit.ps
+}
+
+pages=`{echo $tmp.*|wc -w}
+
+# use delimiters that are unlikely to be supplied in arguments
+echo -n s∮FAXddd∮ >$script
+echo -n `{date} >>$script
+echo ∮ >>$script
+echo -n s∮FAXFFF∮ >>$script
+echo -n $myname >>$script
+echo ∮ >>$script
+echo -n s∮FAXEEE∮ >>$script
+echo -n $user >>$script
+echo ∮ >>$script
+echo -n s∮FAXVVV∮ >>$script
+echo -n $ext >>$script
+echo ∮ >>$script
+echo -n s∮FAXTTT∮ >>$script
+echo -n $recip >>$script
+echo ∮ >>$script
+echo -n s∮FAXfff∮ >>$script
+echo -n $telno >>$script
+echo ∮ >>$script
+echo -n s∮FAXPPP∮ >>$script
+echo -n $pages >>$script
+echo ∮ >>$script
+sed -f $script /sys/lib/fax/h.ps > $header
+
+gs -dSAFER '-sDEVICE=dfaxlow' '-sOUTPUTFILE='$header'.%.3d' -dNOPAUSE -dQUIET $header quit.ps
+
+files=()
+for(i in $header.* $tmp.*){
+ files=($files -f $i)
+}
+
+switch($view){
+case no
+ upas/qer $files /mail/faxoutqueue fax $user $telno < /dev/null
+ rx fax /sys/lib/fax/faxgoose
+case yes
+ page $header.* $tmp.*
+}
+
+#rm -f $tmp.* $header $script $header.* $tmpin
--- /dev/null
+++ b/rc/bin/psu
@@ -1,0 +1,20 @@
+#!/bin/rc
+# psu - ps for just one user
+rfork e
+flags=()
+while (! ~ $#* 0 && ~ $1 -*) {
+ flags = ($flags $1)
+ shift
+}
+
+# sed -n p rather than grep so that we get buffered writes.
+# this is a huge difference in drawterm.
+switch($#*){
+case 0
+ ps $flags | sed -n '/^'$user' /p'
+case 1
+ ps $flags | sed -n '/^'$1' /p'
+case *
+ echo Usage: psu '[ps-flags] [ user ]' >[1=2]
+ exit usage
+}
--- /dev/null
+++ b/rc/bin/readweb
@@ -1,0 +1,10 @@
+#!/bin/rc
+# start abaco and its prerequisites
+rfork n
+
+# outside && bind /net.alt /net
+
+webfs
+webcookies
+echo useragent netscape 1.0 >/mnt/web/ctl
+exec /$cputype/bin/abaco $*
--- /dev/null
+++ b/rc/bin/reboot
@@ -1,0 +1,2 @@
+#!/bin/rc
+echo reboot $* > /dev/reboot
--- /dev/null
+++ b/rc/bin/replica/changes
@@ -1,0 +1,15 @@
+#!/bin/rc
+
+rfork en
+
+fn usage {
+ echo 'usage: replica/changes replica-name [paths]' >[1=2]
+ exit usage
+}
+
+. /rc/bin/replica/defs $*
+
+need clientdb clientroot clientproto
+
+must clientmount
+exec replica/updatedb -p $clientproto -l -r $clientroot $clientexclude $clientdb $paths
--- /dev/null
+++ b/rc/bin/replica/defs
@@ -1,0 +1,55 @@
+tmp=()
+
+fn fatal {
+ if(! ~ $#tmp 0)
+ rm -f $tmp
+ echo $* >[1=2]
+ exit $"*
+}
+
+fn must {
+ $* || fatal $"*^': '^$status
+}
+
+fn need {
+ for(i)
+ if(~ $$i UNCONFIGURED)
+ fatal $name^' does not set $'^$i
+}
+
+opt=()
+while(! ~ $#* 0 && ~ $1 -*){
+ if(~ $1 -s -c){ # take one argument
+ opt=($opt $1)
+ shift
+ }
+ opt=($opt $1)
+ shift
+}
+if(~ $1 --)
+ shift
+if(~ $#* 0)
+ usage
+name=$1
+shift
+paths=($*)
+
+if(! ~ $name /* ./* ../*)
+ name=$home/lib/replica/$name
+
+if(! test -x $name)
+ fatal no such replica $name
+
+cfgopt=()
+applyopt=()
+fn servermount { status='' }
+fn clientmount { status='' }
+fn serverupdate { status='' }
+for (i in clientroot clientproto clientdb clientexclude serverroot serverlog serverproto)
+ $i=UNCONFIGURED
+. $name
+
+if(! ~ $#serverexclude 0)
+ serverexclude=-x^$serverexclude
+if(! ~ $#clientexclude 0)
+ clientexclude=-x^$clientexclude
--- /dev/null
+++ b/rc/bin/replica/pull
@@ -1,0 +1,58 @@
+#!/bin/rc
+
+rfork en
+
+fn usage {
+ echo 'usage: replica/pull [-nv] [-c name] [-s name] replica-name [paths]' >[1=2]
+ exit usage
+}
+
+. /rc/bin/replica/defs $*
+
+need clientlog serverlog clientdb clientroot serverroot
+
+# mount the server file system, update the log
+must servermount
+must serverupdate
+must clientmount
+
+# download the log
+n=`{ls -l $clientlog >[2]/dev/null |awk '{print $6}'}
+s=`{ls -l $serverlog >[2]/dev/null |awk '{print $6}'}
+if(~ $n 0 || ~ $#n 0 || test $s -lt $n){
+ if(test -e $clientlog) must rm $clientlog
+ must fcp $serverlog $clientlog
+}
+if not{
+ m=`{echo $n-1024 | hoc}
+ if(~ $m -*)
+ m=0
+ cmp -s $serverlog $clientlog $m $m
+ x=$status
+ switch($x){
+ case *': EOF'
+ must tail +^$n^c $serverlog >>$clientlog
+ case *': differ'
+ must rm $clientlog
+ must fcp $serverlog $clientlog
+ case ''
+ ;
+ case *
+ fatal cmp: $x
+ }
+}
+
+# normally we'd do this after applylog, but we want
+# applylog to be the last thing in this script, so we'll
+# do it here instead, compacting changes from the
+# _last_ applylog.
+
+ndb=`{echo $clientdb | sed 's;(.*)/(.*);\1/_\2;'}
+must replica/compactdb $clientdb >$ndb
+mv $ndb $clientdb
+
+# mount the client file system, apply the log
+# this is the last thing in the script and is execed so that
+# if replica/pull is overwritten nothing bad will happen.
+# applylog takes care of itself as far as protection against being overwritten.
+exec replica/applylog $opt $applyopt $clientdb $clientroot $serverroot $paths <$clientlog
--- /dev/null
+++ b/rc/bin/replica/push
@@ -1,0 +1,18 @@
+#!/bin/rc
+
+rfork en
+
+fn usage {
+ echo 'usage: replica/push [-nv] replica-name [paths]' >[1=2]
+ exit usage
+}
+
+. /rc/bin/replica/defs $*
+
+need clientproto clientexclude cfgopt clientdb clientroot serverroot paths
+
+must servermount
+must clientmount
+exec replica/applychanges -p $clientproto $clientexclude $opt $cfgopt \
+ $clientdb $clientroot $serverroot $paths
+
--- /dev/null
+++ b/rc/bin/replica/scan
@@ -1,0 +1,18 @@
+#!/bin/rc
+
+rfork en
+
+fn usage {
+ echo 'usage: replica/scan replica-name [paths]' >[1=2]
+ exit usage
+}
+
+. /rc/bin/replica/defs $*
+
+need serverroot serverexclude serverproto serverdb serverlog
+
+must servermount
+replica/updatedb -r^$serverroot $serverexclude -p^$serverproto $serverdb >>$serverlog
+ndb=`{echo $serverdb | sed 's;(.*)/(.*);\1/n\2;'}
+odb=`{echo $serverdb | sed 's;(.*)/(.*);\1/_\2;'}
+replica/compactdb $serverdb >$ndb && mv $serverdb $odb && mv $ndb $serverdb
--- /dev/null
+++ b/rc/bin/replica/setupdirs
@@ -1,0 +1,34 @@
+#!/bin/rc
+
+rfork en
+
+if(! ~ $#libreplica 1)
+ libreplica=$home/lib/replica
+
+fn usage {
+ echo 'usage: replica/setupdirs' >[1=2]
+ exit usage
+}
+
+fn fatal {
+ echo $* >[1=2]
+ exit $"*
+}
+
+fn must {
+ $* || fatal $"*^': '^$status
+}
+
+if(! ~ $#* 0)
+ usage
+
+for (i in \
+ $libreplica\
+ $libreplica/db\
+ $libreplica/db/client\
+ $libreplica/db/server\
+ $libreplica/log\
+ $libreplica/cfg)
+ if(! test -d $i)
+ must mkdir -p $i
+
--- /dev/null
+++ b/rc/bin/rwd
@@ -1,0 +1,23 @@
+#!/bin/rc
+
+rfork e
+if(! ~ $#* 1){
+ echo 'usage: remotesys=xxx rwd dir' >[1=2]
+ exit usage
+}
+
+suf=''
+if(~ $#remotesys 1)
+ suf = @$remotesys
+if not
+ remotesys=''
+
+echo -n $1 >/dev/wdir
+b=`{basename $1}
+if(! ~ $#b 1)
+ b=/
+echo -n $b^$suf >/dev/label
+if(test -f /dev/acme/ctl){
+ echo name $1/-$remotesys >/dev/acme/ctl
+ echo dumpdir $1 >/dev/acme/ctl
+}
--- /dev/null
+++ b/rc/bin/seemail
@@ -1,0 +1,4 @@
+#!/bin/rc
+
+if(~ $1 -i) exec faces -hi
+if not exec faces -h
--- /dev/null
+++ b/rc/bin/service.auth/authsrv.il566
@@ -1,0 +1,2 @@
+#!/bin/rc
+/bin/auth/authsrv -d $3
--- /dev/null
+++ b/rc/bin/service.auth/authsrv.tcp567
@@ -1,0 +1,2 @@
+#!/bin/rc
+/bin/auth/authsrv -d $3
--- /dev/null
+++ b/rc/bin/service/!il17007
@@ -1,0 +1,4 @@
+#!/bin/rc
+
+netdir=`{echo $3 | sed 's;/[0-9]+$;!*!0;'}
+exec exportfs -a -A $netdir
--- /dev/null
+++ b/rc/bin/service/!il17008
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec /bin/exportfs -s
--- /dev/null
+++ b/rc/bin/service/!il17031
@@ -1,0 +1,3 @@
+#!/bin/rc
+exec ramfs -i
+
--- /dev/null
+++ b/rc/bin/service/!tcp515
@@ -1,0 +1,5 @@
+#!/bin/rc
+
+if(/sys/lib/lp/bin/lpscratch){
+ exec /$cputype/bin/aux/lpdaemon >>[2] `{cat /env/LPSCRATCH}^/log/lpdaemonl
+}
--- /dev/null
+++ b/rc/bin/service/!tcp564
@@ -1,0 +1,3 @@
+#!/bin/rc
+mount '#s/boot' /root $rootspec
+exec /bin/exportfs -r /root
--- /dev/null
+++ b/rc/bin/service/startcifs
@@ -1,0 +1,14 @@
+#!/bin/rc
+# startcifs - (re)start cifs (smb) server
+echo killing old cifs server
+Kill aquarela | rc
+
+echo starting new cifs server
+@ {
+ echo 'srv -A local' >>/srv/fscons
+ sleep 2
+ chmod 666 /srv/local
+ 9fs local
+ cd /sys/log
+ aquarela
+} &
--- /dev/null
+++ b/rc/bin/service/startnfs
@@ -1,0 +1,9 @@
+#!/bin/rc
+9fs nslocum
+9fs alice
+Kill portmapper|rc
+Kill nfsserver|rc
+rm -f /srv/nfsserver.chat /srv/portmapper.chat
+aux/nfsserver -a il!emelie -a il!choline -c /lib/ndb/nfs >>[2] /sys/log/nfsserver
+aux/portmapper >>[2] /sys/log/portmapper
+aux/portmapper -t >>[2] /sys/log/portmapper
--- /dev/null
+++ b/rc/bin/service/tcp110
@@ -1,0 +1,3 @@
+#!/bin/rc
+
+exec /$cputype/bin/upas/pop3 -t /sys/lib/ssl/cert.pem >>[2] /sys/log/pop3
--- /dev/null
+++ b/rc/bin/service/tcp113
@@ -1,0 +1,4 @@
+#!/bin/rc
+x=`{read|sed 's/ //'}
+y=`{echo -n $x | sed 's/ //g'}
+echo $y^:USERID:UNIX:none
--- /dev/null
+++ b/rc/bin/service/tcp143
@@ -1,0 +1,3 @@
+#!/bin/rc
+
+exec /bin/ip/imap4d >[2]/sys/log/imap4d
--- /dev/null
+++ b/rc/bin/service/tcp17005
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec /bin/ocpu -f -R
--- /dev/null
+++ b/rc/bin/service/tcp17006
@@ -1,0 +1,1 @@
+#!/bin/ocpu -N
--- /dev/null
+++ b/rc/bin/service/tcp17007
@@ -1,0 +1,3 @@
+#!/bin/rc
+netdir=`{echo $3 | sed 's;/[0-9]+$;!*!0;'}
+exec /bin/exportfs -a -A $netdir
--- /dev/null
+++ b/rc/bin/service/tcp17009
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec /bin/ip/rexexec
--- /dev/null
+++ b/rc/bin/service/tcp17010
@@ -1,0 +1,1 @@
+#!/bin/cpu -R
--- /dev/null
+++ b/rc/bin/service/tcp17013
@@ -1,0 +1,1 @@
+#!/bin/cpu -O
--- /dev/null
+++ b/rc/bin/service/tcp19
@@ -1,0 +1,2 @@
+#!/bin/rc
+/bin/aux/write 4096
--- /dev/null
+++ b/rc/bin/service/tcp21
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec /bin/ip/ftpd $*
--- /dev/null
+++ b/rc/bin/service/tcp22
@@ -1,0 +1,3 @@
+#!/bin/rc
+
+exec /bin/aux/sshserve -A 'tis password' `{cat $3/remote} >>[2]/sys/log/ssh
--- /dev/null
+++ b/rc/bin/service/tcp23
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec /bin/ip/telnetd $*
--- /dev/null
+++ b/rc/bin/service/tcp25
@@ -1,0 +1,5 @@
+#!/bin/rc
+#smtp serv net incalldir user
+
+user=`{cat /dev/user}
+exec upas/smtpd -n $3
--- /dev/null
+++ b/rc/bin/service/tcp513
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec /bin/ip/rlogind
--- /dev/null
+++ b/rc/bin/service/tcp53
@@ -1,0 +1,2 @@
+#!/bin/rc
+/bin/ndb/dnstcp $3
--- /dev/null
+++ b/rc/bin/service/tcp565
@@ -1,0 +1,7 @@
+#!/bin/rc
+#whoami service net dir
+loc=`{cat $3/local|sed 's/!.*//'}
+rem=`{cat $3/remote}
+port=`{echo $rem|sed 's/^[^!]*!//'}
+rem=`{echo $rem|sed 's/!.*//'}
+echo i am $loc sysname $sysname you are $rem port $port
--- /dev/null
+++ b/rc/bin/service/tcp7
@@ -1,0 +1,2 @@
+#!/bin/rc
+/bin/cat
--- /dev/null
+++ b/rc/bin/service/tcp9
@@ -1,0 +1,2 @@
+#!/bin/rc
+cat > /dev/null
--- /dev/null
+++ b/rc/bin/service/tcp993
@@ -1,0 +1,3 @@
+#!/bin/rc
+
+exec tlssrv -c/sys/lib/ssl/cert.pem -limap4d -r`{cat $3/remote} /bin/ip/imap4d -pdplan9.bell-labs.com -r`{cat $3/remote}>[2]/sys/log/imap4d
--- /dev/null
+++ b/rc/bin/service/tcp995
@@ -1,0 +1,3 @@
+#!/bin/rc
+
+exec tlssrv -lpop3 -c/sys/lib/ssl/cert.pem -r`{cat $3/remote} /bin/upas/pop3 -p -r`{cat $3/remote} >[2]/sys/log/pop3
--- /dev/null
+++ b/rc/bin/service/telcodata
@@ -1,0 +1,3 @@
+#!/bin/rc
+echo This is the plan 9 incoming fax line.
+echo Please do not make data calls to us.
--- /dev/null
+++ b/rc/bin/service/telcofax
@@ -1,0 +1,4 @@
+#!/bin/rc
+9fs emelie
+bind -c /n/emelie/mail/faxqueue /mail/faxqueue
+exec /bin/aux/faxreceive
--- /dev/null
+++ b/rc/bin/setrtc
@@ -1,0 +1,4 @@
+#!/bin/rc
+# setrtc - set real-time clock to current system time
+if (test -e '#r/rtc')
+ awk '{print $1}' /dev/time >'#r/rtc'
--- /dev/null
+++ b/rc/bin/sig
@@ -1,0 +1,29 @@
+#!/bin/rc
+# Usage: sig key ...
+# prints out function signatures by grepping the manual
+
+
+*=`{echo $*|tr A-Z a-z|tr -dc 'a-z0-9_ \012'} # fold case, delete funny chars
+if(~ $#* 0){
+ echo Usage: sig function ... >/fd/2
+ exit 1
+}
+
+for (i) {
+ files=`{grep -il '[ ]\*?'$i'\(' /sys/man/2/*}
+ for(j in $files) {
+ {echo .nr LL 20i; sed -n '/^.SH SYNOPSIS/,/^.SH.*DESCR/p' $j } |
+ nroff -man |
+ sed '
+ :a
+ /,$/ {
+ N
+ s/\n//
+ }
+ ta
+ s/[ ]+/ /g' |
+ grep -i -e '[ *]'$i'\(' | sed 's/^[ +]/ /'
+ }
+}
+
+exit 0
--- /dev/null
+++ b/rc/bin/slay
@@ -1,0 +1,7 @@
+#!/bin/rc
+U=`{cat /dev/user}
+for(i){
+ ps | sed -n '/^'$U' .* '$i'$/s%[^ ]* *%~>/proc/%
+ s% *.* (.*)%/ctl # \1%
+ s%~%echo kill%p'
+}
--- /dev/null
+++ b/rc/bin/spell
@@ -1,0 +1,21 @@
+#!/bin/rc
+
+spellflags=()
+deroffargs=()
+fflag=''
+for(x){
+ switch($x){
+ case -[abcvx]
+ spellflags=($spellflags $x)
+ case -f
+ fflag=$x
+ case *
+ if(~ $fflag -f) {
+ spellflags=($spellflags -f $x)
+ fflag=''
+ }
+ if not deroffargs=($deroffargs $x)
+ }
+}
+
+deroff -w $deroffargs | sort -u | aux/sprog $spellflags
--- /dev/null
+++ b/rc/bin/src
@@ -1,0 +1,55 @@
+#!/bin/rc
+
+rfork e
+path=(/bin/)
+
+sym = 'threadmain?z
+ main?z'
+
+fn dbsrc{
+ echo $sym | db $1 | sed '1d;/symbol not found/d;s/.*\(\) //'
+}
+
+fn go{
+ type=`{file <$1 | sed 's/stdin: //'}
+ switch($type){
+ case 'rc executable file'
+ plumbit $1 '(rc executable)'
+ case *executable* *'plan 9 boot image'*
+ plumbit `{dbsrc $1} '(executable)'
+ case *
+ echo 'src: can''t find source for '$1 - unrecognized type $type >[1=2]
+ }
+}
+
+fn plumbit{B $1}
+
+fn usage{
+ echo usage: 'src [-n] [-s symbol] executable ...'>[1=2]
+ exit usage
+}
+
+while(~ $1 -*)
+ switch($1){
+ case -n
+ shift
+ fn plumbit {echo $1}
+ case -s
+ shift
+ # add main in case symbol is undefined
+ sym=$1'?z
+ main?z'
+ shift
+ case -*
+ usage
+ }
+
+if(~ $#* 0) usage
+
+for(i){
+ if(test -f $i) go $i
+ if not if(test -f /bin/$i) go /bin/$i
+ if not if(test -f /bin/*/$i) go /bin/*/$i
+ if not if(test -f /bin/*/*/$i) go /bin/*/*/$i
+ if not echo 'src: can''t find '$i
+}
--- /dev/null
+++ b/rc/bin/srvssh
@@ -1,0 +1,101 @@
+#!/bin/rc
+
+# Serve Unix u9fs over SSH
+#
+# Basically, try each of the following until you find one that works:
+#
+# srvssh unix
+# srvssh -r unix
+# srvssh -R unix
+# srvssh -r -s unix
+# srvssh -R -s unix
+#
+# and then never look back. Note that "srvssh unix" should always
+# work. It's just that if you're talking with certain sshd's, you'll get
+# hit by Nagle's algorithm and need to explore the other flags.
+
+# When using ssh to start u9fs, the only way to turn off
+# Nagle's algorithm (which kills the performance of RPC-based
+# protocols like 9P) is to allocate a pseudo-terminal. The
+# command ssh -Rmp attempts to allocate a pseudo-terminal and
+# then put it in a transparent mode. Especially when
+# connected to older SSH daemons, the connection ends up not
+# quite transparent. To get around this, we explicity set the tty
+# mode on the command line as well. The hope is that -Rmp makes
+# the connection transparent enough for the Tversion, and the stty
+# command will do the rest. If -Rmp doesn't make the connection
+# transparent enough for the Tversion (but the stty commands do
+# make the connection fully transparent) then add "-s 5" to the srv
+# command to tell it to wait 5 seconds before sending the Tversion.
+# That should be enough time for the stty to take effect.
+
+rfork e
+
+fn usage {
+ echo 'usage: srvssh [-R] [-r] [-s] [-u u9fspath] system [srvname [mtpt]]' >[1=2]
+ exit usage
+}
+
+rawhack=''
+sleephack=()
+u9fspath=u9fs
+rawflags=''
+
+while(~ $1 -*){
+ switch($1){
+ case -r
+ rawflags='-Rmp'
+ shift
+ case -R
+ rawflags='-Rmp'
+ rawhack=('stty raw -echo '';''')
+ shift
+ case -s
+ sleephack=(-s 5)
+ shift
+ case -u
+ shift
+ u9fspath=$1
+ shift
+ case -u*
+ u9fspath=`{echo $1 | sed s/-u//}
+ shift
+ case *
+ usage
+ }
+}
+
+if(! ~ $#* 1 2 3)
+ usage
+
+switch($#*){
+case 1
+ srv=$1
+ mtpt=/n/$1
+case 2
+ srv=$2
+ mtpt=/n/$1
+case 3
+ srv=$2
+ mtpt=$3
+}
+
+x=(srv $sleephack -e \
+ 'ssh '$rawflags' '$1' '$rawhack' '$u9fspath' -na none -u ''$''USER -l ''$''HOME/u9fs.log' \
+ $srv $mtpt)
+$x
+
+# Sometimes /srv/whatever can be a closed pipe, in which case
+# srv will have been killed for writing to it, without a chance to
+# defend itself. Rerun it in this case.
+
+ss=$status
+if(~ $ss *'write on closed pipe'*){
+ rm -f /srv/$srv
+ $x
+ ss=$status
+}
+
+if(! ~ $ss '')
+ echo srvssh: $ss >[1=2]
+exit $ss
--- /dev/null
+++ b/rc/bin/start
@@ -1,0 +1,5 @@
+#!/bin/rc
+U=`{cat /dev/user}
+ps | sed -n '/^'$U' .*Stopped.* '$1'$/s%[^ ]* *%~>/proc/%
+s% *.*%/ctl%
+s%~%echo start%p'
--- /dev/null
+++ b/rc/bin/startupasfs
@@ -1,0 +1,5 @@
+#!/bin/rc
+# startupasfs - start upas/fs if needed, mainly for lib/profile
+if (! test -e /srv/upasfs.$user)
+ upas/fs -s
+mount -c /srv/upasfs.$user /mail/fs
--- /dev/null
+++ b/rc/bin/stock
@@ -1,0 +1,14 @@
+#!/bin/rc
+
+stock=ALU
+
+if(! ~ $#* 0) stock=`{echo $*|tr a-z A-Z|sed 's/ /+/g'}
+
+hget 'http://download.finance.yahoo.com/d/quotes.csv?s='^$stock^'&f=snl1d1c1v&e=.exe' |
+ sed 's/ +"/"/;s/ //' |
+ switch(`{date}){
+ case *'Apr 1 '*
+ sed 's/("ALU","ALCATEL LUCENT"),([^,]*),(.*)$/\1,72.35,\3/'
+ case *
+ cat
+ }
--- /dev/null
+++ b/rc/bin/stop
@@ -1,0 +1,5 @@
+#!/bin/rc
+U=`{cat /dev/user}
+ps | sed -n '/^'$U' .* '$1'$/s%[^ ]* *%~>/proc/%
+s% *.*%/ctl%
+s%~%echo stop%p'
--- /dev/null
+++ b/rc/bin/tel
@@ -1,0 +1,8 @@
+#!/bin/rc
+rfork e
+for(i){
+ if (test -f $home/lib/tel)
+ grep -i $i $home/lib/tel
+ grep -hi $i /lib/tel /lib/areacodes
+}
+exit ''
--- /dev/null
+++ b/rc/bin/termrc
@@ -1,0 +1,106 @@
+#!/bin/rc
+# terminal startup
+TIMESYNCARGS=(-rLa1000000)
+NDBFILE=/lib/ndb/local
+
+mntgen -s slashn && chmod 666 /srv/slashn
+
+# bind all likely devices (#S was bound in boot)
+for(i in f t m v L P u U '$' Σ κ)
+ /bin/bind -a '#'^$i /dev >/dev/null >[2=1]
+
+# set up any partitions
+diskparts
+
+# start up local swapping
+disk=`{ls /dev/sd*/swap >[2]/dev/null}
+if (! ~ $#disk 0)
+ swap $disk(1) >/dev/null >[2=1]
+rm /env/disk
+
+# we do this before we have a name. we may need to do network
+# setup so that we can get a name.
+if(test -e /rc/bin/termrc.local)
+ . /rc/bin/termrc.local
+
+# cs sets sysname (termrc.local may already have started it so check)
+if(! test -e /srv/cs && ! test -e /net/cs)
+ ndb/cs -f $NDBFILE
+sysname=`{cat /dev/sysname}
+if (~ $#sysname 0 || ~ $sysname '') {
+ sysname = gnot # default
+ echo -n $sysname >/dev/sysname
+}
+
+# machine specific startup (e.g., for devices not probed)
+if(test -e /cfg/$sysname/termrc)
+ . /cfg/$sysname/termrc
+
+# start IP on the LAN, if not already configured. diskless terminals
+# are already configured by now. It's commented out to avoid a long timeout
+# on startup waiting for DHCP.
+#
+# If your site provides DHCP service,
+#
+#if(! test -e /net/ipifc/0/ctl)
+# ip/ipconfig
+#
+# Otherwise, see /cfg/$sysname/termrc (/cfg/example/termrc is an example).
+
+# start dns if we have an internet
+if(test -e /net/ipifc/0/ctl && ! test -e /srv/dns)
+ ndb/dns -r
+
+if(! ~ $terminal *vx32*){
+ # start timesync if it isn't running and we weren't told not to
+ if(! ps|grep -s timesync)
+ if(! ~ $TIMESYNCARGS '')
+ aux/timesync $TIMESYNCARGS
+
+ # add the loop-back medium
+ if(! grep -s 127.0.0.1 /net/ipselftab)
+ ip/ipconfig loopback /dev/null 127.1
+
+ # set things up for vmware
+ if(! ~ `{cat /dev/user} none)
+ if(test -e /bin/aux/vmware)
+ aux/vmware
+}
+
+# query user if terminal isn't adequately configured yet
+if(~ $mouseport ask){
+ echo -n 'mouseport is (ps2, ps2intellimouse, 0, 1, 2)[ps2]: '
+ mouseport=`{read}
+ if(~ $#mouseport 0)
+ mouseport=ps2
+}
+if(~ $vgasize ask){
+ echo -n 'vgasize [640x480x8]: '
+ vgasize=`{read}
+ if(~ $#vgasize 0)
+ vgasize=640x480x8
+}
+if(~ $monitor ask){
+ echo -n 'monitor is [xga]: '
+ monitor=`{read}
+ if(~ $#monitor 0)
+ monitor=xga
+}
+if(test -f /dev/mousectl){
+ switch($mouseport){
+ case ps2 ps2intellimouse 0 1 2
+ aux/mouse $mouseport
+ # parse vgasize into fields
+ vgasize=`{echo $vgasize}
+ if(! ~ $"monitor '' && ! ~ `{cat /dev/user} none)
+ aux/vga -l $vgasize
+ if(~ $accupoint 1)
+ pipefile -dr /bin/aux/accupoint /dev/mouse
+ }
+}
+
+usbstart
+if (test -f /dev/apm)
+ aux/apm
+
+dontkill '^(ipconfig|factotum|mntgen|fossil|cs|dns|listen|reboot)$'
--- /dev/null
+++ b/rc/bin/termrc.local
@@ -1,0 +1,13 @@
+#!/bin/rc
+# local terminal startup
+
+# used only by upas, as default return domain appended to all unqualified
+# return addresses, even local ones
+site=plan9
+# replace FILESERVER with the name of your file server
+# here we start with kfs, your local disk file system
+fileserver=kfs
+# replace FACEDOM with the local domain to be used in the faces database
+facedom=FACEDOM
+# replace CPU with the name of your cpu server
+cpu=CPU
--- /dev/null
+++ b/rc/bin/thesaurus
@@ -1,0 +1,29 @@
+#!/bin/rc
+
+hget 'http://thesaurus.reference.com/search?q='^$1 |
+ htmlfmt -l 1000 |
+ sed -n '/^Main Entry:/,/^Source/ {
+ /^Source/ q
+ /^[A-Z].*:/ {
+ N
+ s/\n/ /g
+ }
+ p
+ }' | awk -F', ' '{
+ if(length($0)<=70){
+ next
+ }
+ l = 0
+ for(i = 1; i < NF; i++){
+ printf "%s ", $i
+ l += length($i)+1
+ if(l > 70){
+ printf "\n\t\t"
+ l = 2*ENVIRON["tabstop"]
+ }
+ }
+ if(l>0)
+ printf "\n"
+ next
+ }'
--- /dev/null
+++ b/rc/bin/tlsclienttunnel
@@ -1,0 +1,7 @@
+#!/bin/rc
+
+if(! ~ $#* 3){
+ echo 'usage: tlsclienttunnel cryptaddr plainaddr cert.thumb' >[1=2]
+ exit usage
+}
+aux/listen1 -t $2 /bin/tlsclient -t $3 $1 &
--- /dev/null
+++ b/rc/bin/tlssrvtunnel
@@ -1,0 +1,7 @@
+#!/bin/rc
+
+if(! ~ $#* 3){
+ echo 'usage: tlssrvtunnel plainaddr cryptaddr cert.pem' >[1=2]
+ exit usage
+}
+aux/listen1 -tv $2 /bin/tlssrv -c $3 -llisten /bin/aux/trampoline $1 &
--- /dev/null
+++ b/rc/bin/troff2gif
@@ -1,0 +1,2 @@
+#!/bin/rc
+{/bin/troff $*|/bin/lp -dstdout|/bin/gs -dNOPAUSE -dQUIET '-sOUTPUTFILE='/fd/1 '-sDEVICE=plan9bm' - quit.ps| crop -c 255 255 255 | togif} >[2] /dev/null
--- /dev/null
+++ b/rc/bin/troff2png
@@ -1,0 +1,9 @@
+#!/bin/rc
+
+troff -ms $* | aux/tr2post |
+ gs -g1000x1600 -r100 -dNOPAUSE -dQUIET \
+ '-dGraphicsAlphaBits=4' '-dTextAlphaBits=4' \
+ '-sOUTPUTFILE=-' '-sDEVICE=plan9' - quit.ps |
+ {crop -c 255 255 255; cat >/dev/null} |
+ topng
+
--- /dev/null
+++ b/rc/bin/umem
@@ -1,0 +1,33 @@
+#!/bin/rc
+# umem pid [binary] - print summary of allocate blocks in a running process
+rfork e
+if(! ~ $#* 1 2){
+ echo 'usage: umem pid [binary]' >[1=2]
+ exit usage
+}
+
+p=$1
+binary=()
+if(~ $#* 2)
+ binary=$2
+
+echo 'blocksummary()' | acid -lpool -lleak $p $binary | awk '
+ $1 == "block" {
+ addr=$6
+ size=$3
+ alloc=$4
+ total[alloc] += size
+ count[alloc]++
+ }
+ $1 == "summary" {
+ alloc=$2
+ cnt=$3
+ size=$4
+ total[alloc] += size
+ count[alloc] += cnt
+ }
+ END{
+ for(i in count)
+ printf("%6d %11d %s\n", count[i], total[i], i);
+ }
+' | sort -nr
--- /dev/null
+++ b/rc/bin/uncompress
@@ -1,0 +1,2 @@
+#!/bin/rc
+exec compress -d $*
--- /dev/null
+++ b/rc/bin/ups
@@ -1,0 +1,32 @@
+#!/bin/rc
+# ups - look up a UPS tracking number
+rfork en
+
+if(! ~ $#* 1) {
+ echo usage: ups 1ZA41W190338680961 >[1=2]
+ exit usage
+}
+
+hget 'http://wwwapps.ups.com/WebTracking/processInputRequest?tracknum='^$1^ \
+ '&TypeOfInquiryNumber=T' >/tmp/ups.1
+
+sed 's/<[Tt][Dd]>/& «TD»/g; s/<[Tt][Rr]>/&<td> «TR» /g' /tmp/ups.1 |
+ htmlfmt >/tmp/ups.2
+sam -d /tmp/ups.2 >[2] /dev/null <<'!'
+/^Tracking results.*/p
+.,$d
+/Help/d
+1,.d
+$-2,$d
+/Status:/+1
+.,/«TR»/-2d
+,s/\n/ /g
+,s/«TR»/\n/g
+,s/«TD»/ /g
+,s/ * */ /g
+,s/^[ ]*//g
+,s/[ ]*$//g
+,s/\n\n+/\n\n/g
+,p
+!
+echo
--- /dev/null
+++ b/rc/bin/uptime
@@ -1,0 +1,8 @@
+#!/bin/rc
+clock=`{cat /dev/time}
+xx=`{{echo $clock(3) / $clock(4); echo '_/86400'}|hoc|sed 's/^\./0./g;s/\..*//g'}
+sec=$xx(1)
+days=$xx(2)
+cat /dev/sysname
+echo -n ' up '$days' days, '
+timezone='MDT -21600' date $sec |awk '{print $4}'
--- /dev/null
+++ b/rc/bin/usbeject
@@ -1,0 +1,41 @@
+#!/bin/rc
+# usbeject - unmount usb disks given as arguments
+# unmount all of them if no arguments given
+rfork e
+disk = ()
+mtpt = /n/usb
+
+test -e /dev/fs/ctl || bind -b '#k' /dev >[2]/dev/null
+
+test -e /dev/usb || bind -a '#u' /dev || {
+ echo $0: no '#u/usb' >[1=2]
+ exit nousb
+}
+test -e /dev/usbdctl || mount -a /srv/usb /dev || {
+ echo $0: cannot mount /srv/usb >[1=2]
+ exit nousbd
+}
+
+disks=()
+mtpt=()
+switch ($#*) {
+case 0
+ disks=`{ls -pd /n/sdU*}
+case *
+ disks=()
+ for (a) {
+ if(~ $a sd??)
+ disk=`{ls -pd /n/^$*^*}
+ if not
+ disk=$a
+ disks=($disks $disk)
+ }
+}
+if (~ $disks '''sdU*''')
+ exit ''
+for (disk in $disks) {
+ unmount /n/$disk >[2]/dev/null && echo $disk unmounted
+ if (test -e /dev/fs/ctl)
+ echo del $disk^parts/^'*' >/dev/fs/ctl >[2]/dev/null
+}
+exit ''
--- /dev/null
+++ b/rc/bin/usbstart
@@ -1,0 +1,24 @@
+#!/bin/rc
+# usbstart - start appropriate usb flavour
+if(test -r '#u'/usb) {
+ if(! test -r /dev/usb)
+ bind -a '#u' /dev
+
+ # /boot/boot may have started usbd, which starts all usb drivers
+ if (! ps | grep -s ' usbd$')
+ usb/usbd
+}
+if not if(test -r '#U'/usb0) {
+ if(! test -r /dev/usb0)
+ bind -a '#U' /dev
+
+ # /boot/boot may have started usbd, usb/kb or usb/disk
+ if (! ps | grep -s ' usbd$')
+ usb/usbd
+ usb/usbmouse -a 2
+ if (! ps | grep -s ' kb$')
+ usb/kb -k
+ usb/usbaudio -s usbaudio.$sysname -V
+ # usb/print
+}
+exit ''
--- /dev/null
+++ b/rc/bin/usps
@@ -1,0 +1,20 @@
+#!/bin/rc
+rfork en
+
+
+if(! ~ $#* 1) {
+ echo usage: usps 01601531218002685498 >[1=2]
+ exit usage
+}
+
+rfork e
+
+hget -p 'origTrackNum='^$1 http://trkcnfrm1.smi.usps.com/PTSInternetWeb/InterLabelInquiry.do |
+ htmlfmt > /tmp/usps.$pid
+
+sam -d /tmp/usps.$pid >[2] /dev/null <<'!'
+0,/Label/-1d
+/^Enter Label/,$d
+,p
+!
+rm /tmp/usps.$pid
--- /dev/null
+++ b/rc/bin/vwhois
@@ -1,0 +1,17 @@
+#!/bin/rc
+
+rfork e
+
+box=mbox
+if(! test -d /mail/fs/$box)
+ box=`{ls -p /mail/fs | grep -v ctl | sed 1q}
+if(~ $#box 0)
+ box=mbox # we tried
+
+if(~ $#box 1 && test -f /mnt/plumb/seemail || test -f /mnt/term/mnt/plumb/seemail){
+ for(i)
+ plumb -dseemail -a 'filetype=vwhois digest='$i.$pid' mailtype=new sender='$i /mail/fs/$box/XXXvwhois
+}
+if not for (i){
+ echo vwhois: vwhois: vwhois: delivered `{cat /dev/user} From $i '(vwho)' >> /sys/log/mail
+}
--- /dev/null
+++ b/rc/bin/wdoc2txt
@@ -1,0 +1,17 @@
+#!/bin/rc
+
+switch($#*){
+case 0
+ exit
+case 1
+ switch($1){
+ case *.rtf
+ pub/rtf2text $1 >[2]/dev/null | plumb -i -d edit -a 'action=showdata filename='$1
+ case *.doc *
+ doc2txt $1 | plumb -i -d edit -a 'action=showdata filename='$1
+ }
+ exit
+case *
+ for(i in *)
+ wdoc2txt $i
+}
--- /dev/null
+++ b/rc/bin/weather
@@ -1,0 +1,46 @@
+#!/bin/rc
+
+rfork e
+
+DEFAULT=ewr
+
+fn usage{
+ echo 'usage: weather 3-letter-city-code' >[1=2]
+ echo 'for a list of cities in new york, say' >[1=2]
+ echo ' weather ny' >[1=2]
+ exit usage
+}
+
+switch($#*){
+case 0
+ arg=$DEFAULT
+ if(~ $#weather 1)
+ arg=$weather
+case 1
+ arg=$1
+case *
+ usage
+}
+
+switch($arg){
+case [a-zA-Z][a-zA-Z][a-zA-Z]
+ script=('' '' 'C' '4' '1' '1' $arg '' '' '' '' 'X')
+case [a-zA-Z][a-zA-Z]
+ script=('' '' 'C' '4' '1' '3' $arg '' '' '' '' 'X')
+case *
+ usage
+}
+
+{
+ for(i in $script)
+ echo $i
+} |
+con -nrl tcp!rainmaker.wunderground.com!telnet |
+sed -n '/Enter .-letter .* code:/,/CITY FORECAST MENU/p' |
+sed 's/Enter .-letter .* code: //' |
+sed 's/ Press Return to continue, M to return to menu, X to exit: //' |
+grep -v 'CITY FORECAST MENU' |
+tr -d ' ' |
+sed 's/ *$//' |
+uniq
+
--- /dev/null
+++ b/rc/bin/who
@@ -1,0 +1,4 @@
+#!/bin/rc
+ps | sed '/Broken/d
+/Exiting/d
+s% .*$%%' | sort -u
--- /dev/null
+++ b/rc/bin/whois
@@ -1,0 +1,9 @@
+#!/bin/rc
+
+for(i in $*)
+ grep '^'$i' ' /adm/whois ||
+ grep -i $i /adm/keys.who ||
+ grep -i $i /adm/netkeys.who ||
+ grep -i $i /adm/whois ||
+ grep -i $i /adm/users ||
+ echo who indeed is $i
--- /dev/null
+++ b/rc/bin/window
@@ -1,0 +1,100 @@
+#!/bin/rc
+# window [many options] cmd [arg...] - create new window and run cmd in it
+rfork e
+fn checkwsys{
+ if(~ $wsys ''){
+ echo 'window: $wsys not defined'
+ exit bad
+ }
+}
+
+# original version used mount to do the work
+fn oldway{
+ switch($#*){
+ case 0 1
+ echo usage: window '''minx miny maxx maxy''' cmd args ...
+ exit usage
+ }
+
+ checkwsys
+
+ dir = /mnt/wsys
+ srv = $wsys
+
+ rfork ne
+ {
+ if(x=`{cat /dev/ppid}; mount $srv $dir N`{{echo $x $1 }| sed 's/^ //g;s/ +/,/g'}){
+ shift
+ bind -b $dir /dev
+ echo -n `{basename $1} > /dev/label >[2] /dev/null
+ exec $* < /dev/cons > /dev/cons >[2] /dev/cons
+ }
+ }&
+}
+
+# if argument is of form '100 100 200 200' or '100,100,200,200' use old way
+if(~ $1 *[0-9][' ,'][0-9]*){
+ oldway $*
+ exit
+}
+
+# geometry parameters are:
+# -r 0 0 100 100
+# -dx n
+# -dy n
+# -minx n
+# -miny n
+# -maxx n
+# -maxy n
+# where n can be a number, to set the value, or +number or -number to change it
+
+# find wctl file
+fn getwctl{
+ if(~ $wctl ''){
+ if(test -f /dev/wctl) echo /dev/wctl
+ if not if(test -f /mnt/term/dev/wctl) echo /mnt/term/dev/wctl
+ if not if(~ $service cpu) echo /mnt/term/srv/riowctl.*.*
+ if not {
+ echo window: '$wctl' not defined >[1=2]
+ exit usage
+ }
+ }
+ if not echo $wctl
+}
+
+# use mount to make local window
+if(~ $1 -m){
+ shift
+
+ checkwsys
+
+ dir = /mnt/wsys
+ srv = $wsys
+ rfork ne
+ {
+ unmount /mnt/acme /dev >[2]/dev/null
+ if(mount $srv $dir 'new -pid '^`{cat /dev/ppid}^' '$"*){
+ bind -b $dir /dev
+ # toss geometry parameters to find command
+ while(~ $1 -*)
+ switch($1){
+ case -dx -dy -minx -miny -maxx -maxy
+ shift 2
+ case -r
+ shift 5
+ case -scroll
+ shift
+ case -noscroll
+ shift
+ case -hide
+ shift
+ }
+ if(~ $#* 0) cmd = rc
+ if not cmd = $*
+ echo -n `{basename $cmd(1)} > /dev/label >[2] /dev/null
+ exec $cmd < /dev/cons > /dev/cons >[2] /dev/cons
+ }
+ }&
+}
+
+if not echo new -cd `{pwd} $* >> `{getwctl}
--- /dev/null
+++ b/rc/bin/wloc
@@ -1,0 +1,10 @@
+#!/bin/rc
+
+rfork e
+ifs='
+'
+
+for(i in `{ls /dev/wsys}) {
+ echo window -r `{syscall -o read 0 buf 59 < $i/window >[2] /dev/null |
+ sed 's/............//; s/^ *//; s/ */ /g'} `{cat $i/label}
+}
--- /dev/null
+++ b/rc/bin/wurl2txt
@@ -1,0 +1,15 @@
+#!/bin/rc
+
+switch($#*){
+case 0
+ exit
+case 1
+ name = /`{echo $1 | sed 's;.*//;;
+ s;/.*;;'}^/webpage
+ # send hget errors to 2 so they appear in window
+ hget $1 >[2=1]| {echo $1; echo; htmlfmt} >[2=1] | plumb -i -d edit -a 'action=showdata filename='$name
+ exit
+case *
+ for(i in *)
+ wurl2txt $i
+}
--- /dev/null
+++ b/rc/bin/xls2txt
@@ -1,0 +1,32 @@
+#!/bin/rc
+
+rfork en
+
+if(! ~ $#* 0 1) {
+ echo 'usage: xls2txt [file.xls]' >[1=2]
+ exit usage
+}
+
+switch($#*){
+case 0
+ cat >/tmp/xls2txt.$pid
+ file=/tmp/xls2txt.$pid
+case 1
+ file=$1
+}
+aux/olefs $file || {
+ echo 'xls2txt: couldn''t mount excel document' >[1=2]
+ rm -f /tmp/xls2txt.$pid
+ exit word
+}
+
+if(! test -f /mnt/doc/Workbook) {
+ echo 'xls2txt: is an MSoffice doc but not an Excel document' >[1=2]
+ rm -f /tmp/xls2txt.$pid
+ exit wordxls
+}
+
+aux/msexceltables /mnt/doc/Workbook
+unmount /mnt/doc
+rm -f /tmp/xls2txt.$pid
+
--- /dev/null
+++ b/rc/bin/yesterday
@@ -1,0 +1,157 @@
+#!/bin/rc
+
+rfork e
+
+
+smon='s/Jan/01/
+ s/Feb/02/
+ s/Mar/03/
+ s/Apr/04/
+ s/May/05/
+ s/Jun/06/
+ s/Jul/07/
+ s/Aug/08/
+ s/Sep/09/
+ s/Oct/10/
+ s/Nov/11/
+ s/Dec/12/'
+
+fn usage {
+ echo 'usage: yesterday [-abcCdDs] [-[[[yy]yy]mm]dd] [-n daysago] file ...' >[1=2]
+ exit 'usage'
+}
+
+fn Xcp {
+ echo cp $1 $2
+ cp $1 $2
+}
+
+fn Xdiff {
+ echo diff $1 $2
+ diff $1 $2
+}
+fn Xdiffn {
+ echo diff -n $1 $2
+ diff -n $1 $2
+}
+fn Xadiff {
+ echo /acme/bin/adiff $1 $2
+ /acme/bin/adiff $1 $2
+}
+
+fn Xcarefulcp {
+ if(! cmp -s $1 $2) Xcp $1 $2
+}
+
+fn Xecho {
+ echo $1
+}
+
+fn Xbind {
+ echo bind $1 $2
+ bind $1 $2
+}
+
+year=`{date|sed 's/.* //'}
+copy=Xecho
+last=()
+defdump=dump
+while(! ~ $#* 0 && ~ $1 -* && ! ~ $1 --){
+ switch($1){
+ case -a
+ copy=Xadiff
+ shift
+ case -b
+ copy=Xbind
+ shift
+ case -c
+ copy=Xcp
+ shift
+ case -d
+ copy=Xdiff
+ shift
+ case -D
+ copy=Xdiffn
+ shift
+ case -C
+ copy=Xcarefulcp
+ shift
+ case -s
+ defdump=snap
+ shift
+ case -n*
+ if(~ $1 -n){
+ if(~ $#* 1)
+ usage
+ shift
+ days=$1
+ }
+ if not
+ days=`{echo $1 | sed 's/^-.//'}
+ last=`{date `{hoc -e `{date -n} ^ '-'$days'*60*60*24'} | \
+ sed -e 's%... (...) (..) ..:..:.. ... (....)%\3/\1\2%' -e 'y/ /0/' -e $smon}
+ shift
+ case -?
+ mon=`{date|sed -e 's/^....(...).*/\1/' -e $smon}
+ last=$year/$mon ^`{echo $1|sed 's/^-/0/'}
+ shift
+ case -??
+ mon=`{date|sed -e 's/^....(...).*/\1/' -e $smon}
+ last=$year/$mon ^`{echo $1|sed 's/^-//'}
+ shift
+ case -????
+ last=$year/ ^ `{echo $1|sed 's/^-//'}
+ shift
+ case -??????
+ last=`{echo $year|sed 's/..$//'} ^ `{echo $1|sed 's/^-(..)/\1\//'}
+ shift
+ case -????????
+ last=`{echo $1|sed 's/^-(....)/\1\//'}
+ shift
+ case *
+ usage
+ }
+}
+if(! ~ $#* 0 && ~ $1 --)
+ shift
+
+if(~ $#* 0)
+ usage
+
+dir=`{pwd}
+if(! ~ $status ''){
+ echo 'yesterday: can''t find directory' >[1=2]
+ exit 'pwd failed'
+}
+
+for(i){
+ xpath=`{cleanname -d $dir -- $i}
+ xdump=$defdump
+ dumppath=$xpath
+ if(~ $xpath /n/*/*){
+ xdump=`{echo $xpath | sed 's:/n/([^/]+)/.*:\1'$defdump':'}
+ dumppath=`{echo $xpath | sed 's:/n/[^/]+(/.*):\1:'}
+ }
+ if(! test -e /n/$xdump/$year)
+ 9fs $xdump
+
+ if(~ $#last 0){
+ xlast=`{ls /n/$xdump/$year|sed -n '$p'}
+ switch($defdump){
+ case snap
+ xlast=`{ls $xlast|sed -n '$p'}
+ }
+ }
+ if not
+ xlast=/n/$xdump/$last
+
+ if(! test -e $xlast){
+ echo 'yesterday:' \
+ `{echo $xlast|sed 's/.n.'$defdump'.(....).(..)(..)/\1 \2 \3/'} \
+ 'is not a backup day for' $xdump >[1=2]
+ exit 'bad date'
+ }
+
+ $copy $xlast^$dumppath $xpath
+}
+exit ''
--- /dev/null
+++ b/rc/lib/rcmain
@@ -1,0 +1,34 @@
+# rcmain: Plan 9 version
+if(~ $#home 0) home=/
+if(~ $#ifs 0) ifs='
+'
+switch($#prompt){
+case 0
+ prompt=('% ' ' ')
+case 1
+ prompt=($prompt ' ')
+}
+if(~ $rcname ?.out) prompt=('broken! ' ' ')
+if(flag p) path=/bin
+if not{
+ finit
+ if(~ $#path 0) path=(. /bin)
+}
+fn sigexit
+if(! ~ $#cflag 0){
+ if(flag l && /bin/test -r $home/lib/profile) . $home/lib/profile
+ status=''
+ eval $cflag
+}
+if not if(flag i){
+ if(flag l && /bin/test -r $home/lib/profile) . $home/lib/profile
+ status=''
+ if(! ~ $#* 0) . $*
+ . -i '#d/0'
+}
+if not if(~ $#* 0) . '#d/0'
+if not{
+ status=''
+ . $*
+}
+exit $status