From e3e07ddd95c3015262397831a4fed6f9be708e41 Mon Sep 17 00:00:00 2001 From: sl Date: Fri, 22 Aug 2025 01:50:41 +0000 Subject: [PATCH] initial import --- sites/plan9.stanleylieber.com/mother/README | 65 +++ .../plan9.stanleylieber.com/mother/facemother | 19 + .../mother/img/ello.co.png | Bin 0 -> 7942 bytes sites/plan9.stanleylieber.com/mother/index.md | 65 +++ sites/plan9.stanleylieber.com/mother/mkfile | 9 + sites/plan9.stanleylieber.com/mother/mother | 504 ++++++++++++++++++ 6 files changed, 662 insertions(+) create mode 100644 sites/plan9.stanleylieber.com/mother/README create mode 100755 sites/plan9.stanleylieber.com/mother/facemother create mode 100644 sites/plan9.stanleylieber.com/mother/img/ello.co.png create mode 100644 sites/plan9.stanleylieber.com/mother/index.md create mode 100755 sites/plan9.stanleylieber.com/mother/mkfile create mode 100755 sites/plan9.stanleylieber.com/mother/mother diff --git a/sites/plan9.stanleylieber.com/mother/README b/sites/plan9.stanleylieber.com/mother/README new file mode 100644 index 0000000..2dc70ad --- /dev/null +++ b/sites/plan9.stanleylieber.com/mother/README @@ -0,0 +1,65 @@ +mother +====== + +Mother is an [rc(1)](http://man.9front.org/1/rc) script that provides +an experience similar to +[nedmail(1)](http://man.9front.org/1/nedmail). + +Download it [here](http://only9fans.com/sl/mother/HEAD/info.html). + +help +---- + + usage: mother [ -d ] [ -f mbox ] [ -p msg ] [ -r ] + + Commands are of the form [] [args] + := | , + := + a reply to sender and recipients + b print the next ten headers + d mark for deletion + e ... enter message (args passed to upas/marshal) + g/regexp/cmd grep headlines for regexp and run cmd on matches + h print message headline (,h for all) + help print this help message + m ... forward mail to address(es) + mb ... change to specified mailbox + p print the processed message + P print the raw message + q quit + r reply to message + s ... store message in specified mailbox + u remove deletion mark + y synchronize with mail box + " print message in quoted form, suitable for reply + |cmd pipe the processed message to a command + ||cmd pipe the raw message to a command + !cmd run a command + +extensions +---------- + +A script may be used in conjunction with +[faces(1)](http://man.9front.org/1/faces) and the +[plumber(4)](http://man.9front.org/4/plumber) to open individual +messages (or the entire mailbox) by clicking mb1 on a face in the +[faces(1)](http://man.9front.org/1/faces) window. Each click produces +a new window containing the selected message. + +The script: +[facemother](https://plan9.stanleylieber.com/rc/facemother) <- read +and modify as needed before using + +The plumber rule: + + # faces -> new mail window for message + type is text + data matches '[a-zA-Z¡-￿0-9_\-./]+' + data matches '/mail/fs/[a-zA-Z¡-￿0-9/]+/[0-9]+' + plumb to showmail + plumb start window -r 646 117 1366 676 facemother $0 + +screenshots +----------- + +![ello.co](img/ello.co.png) diff --git a/sites/plan9.stanleylieber.com/mother/facemother b/sites/plan9.stanleylieber.com/mother/facemother new file mode 100755 index 0000000..facd29f --- /dev/null +++ b/sites/plan9.stanleylieber.com/mother/facemother @@ -0,0 +1,19 @@ +#!/bin/rc +# 2018-02-15T21:12:06-0500 +# helper program for launching http://plan9.stanleylieber.com/mother from faces(1). +rfork en + +# plumber rules for faces(1) +#type is text +#data matches '[a-zA-Z¡-￿0-9_\-./]+' +#data matches '/mail/fs/[a-zA-Z¡-￿0-9/]+/[0-9]+' +#plumb to showmail +#plumb start window -r 583 206 1303 1200 facemother $0 + +# open and print only the indicated message +msg=`{sed -n 19p $1/info} +upas/fs -f /mail/box/sl/mbox/$msg +mother -p 1 + +# use existing mailbox, print the indicated message +#mother -p `{basename $1} diff --git a/sites/plan9.stanleylieber.com/mother/img/ello.co.png b/sites/plan9.stanleylieber.com/mother/img/ello.co.png new file mode 100644 index 0000000000000000000000000000000000000000..93ce22775d4d349370c4c44cd72085e8f1341026 GIT binary patch literal 7942 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] [args] + := | , + := + a reply to sender and recipients + b print the next ten headers + d mark for deletion + e ... enter message (args passed to upas/marshal) + g/regexp/cmd grep headlines for regexp and run cmd on matches + h print message headline (,h for all) + help print this help message + m ... forward mail to address(es) + mb ... change to specified mailbox + p print the processed message + P print the raw message + q quit + r reply to message + s ... store message in specified mailbox + u remove deletion mark + y synchronize with mail box + " print message in quoted form, suitable for reply + |cmd pipe the processed message to a command + ||cmd pipe the raw message to a command + !cmd run a command + +extensions +---------- + +A script may be used in conjunction with +[faces(1)](http://man.9front.org/1/faces) and the +[plumber(4)](http://man.9front.org/4/plumber) to open individual +messages (or the entire mailbox) by clicking mb1 on a face in the +[faces(1)](http://man.9front.org/1/faces) window. Each click produces +a new window containing the selected message. + +The script: +[facemother](https://plan9.stanleylieber.com/rc/facemother) <- read +and modify as needed before using + +The plumber rule: + + # faces -> new mail window for message + type is text + data matches '[a-zA-Z¡-￿0-9_\-./]+' + data matches '/mail/fs/[a-zA-Z¡-￿0-9/]+/[0-9]+' + plumb to showmail + plumb start window -r 646 117 1366 676 facemother $0 + +screenshots +----------- + +![ello.co](img/ello.co.png) diff --git a/sites/plan9.stanleylieber.com/mother/mkfile b/sites/plan9.stanleylieber.com/mother/mkfile new file mode 100755 index 0000000..e72fed0 --- /dev/null +++ b/sites/plan9.stanleylieber.com/mother/mkfile @@ -0,0 +1,9 @@ +web:V: + cp README index.md + if(test -f mother.tgz) + rm mother.tgz + cd .. + tar zcvf /tmp/mother.tgz mother + cd mother + cp /tmp/mother.tgz ../src/ + rm /tmp/mother.tgz diff --git a/sites/plan9.stanleylieber.com/mother/mother b/sites/plan9.stanleylieber.com/mother/mother new file mode 100755 index 0000000..b700e0c --- /dev/null +++ b/sites/plan9.stanleylieber.com/mother/mother @@ -0,0 +1,504 @@ +#!/bin/rc +# 2022-11-16T18:11:20-05:00 +# Mother wants to talk to you. +# Similar to nedmail. Use with 9front or nupas/fs (creates mdir format files on save). +# BONUS: Helper program for use with faces(1): http://plan9.stanleylieber.com/mother/facemother +rfork en +ramfs -p +argv0=$0 +if(~ $#editor 0) + editor=hold +if(~ $#pager 0) + pager=cat +mb=mbox +msg=() +sort=-r +fn d{ + if(test $1 -le $#rposts && test -d $rposts($1)){ + flag +D $1 && + dposts=($dposts $1) || + echo !delete $1 failed + } + if not + echo !address +} +fn deldposts{ + + + ndel=() + for(i in $dposts){ + if(test $i -le $#rposts && test -d $rposts($i)){ + echo delete $mb $rposts($i) >/mail/fs/ctl && + echo !deleted $i && + ndel=($ndel $i) || + echo !delete $i failed + } + } + echo !$#ndel messages deleted + + +} +fn e{ + >/tmp/e && + eval $editor /tmp/e && + yn send && + if(~ $yn y) + /bin/upas/marshal $* $rposts($2)^/flags && + puth $2 || + echo !address + } +} +fn fmtd{ + date=`{read} + switch($date(2)){ + case Jan; mo=1 + case Feb; mo=2 + case Mar; mo=3 + case Apr; mo=4 + case May; mo=5 + case Jun; mo=6 + case Jul; mo=7 + case Aug; mo=8 + case Sep; mo=9 + case Oct; mo=10 + case Nov; mo=11 + case Dec; mo=12 + } + switch($date(3)){ + case [0-9] + da=0^$date(3) + case * + da=$date(3) + } + switch($date(6)){ + case `{date | awk '{print $6;}'} + ti=`{echo $date(4) | awk '{print substr($0,0,5);}'} + case * + ti=$date(6) + } + echo $mo/$da $ti +} +fn geth{ + for(i in $*){ + flags=`{sed -n 18p $rposts($i)^/info | sed 's/-//g'} + mime=`{ + if(~ `{sed -n 7p $rposts($i)^/info} multipart*) + echo H + } + size=`{sed -n 17p $rposts($i)^/info} + date=`{sed -n 5p $rposts($i)^/info | fmtd} + from=`{sed -n 1p $rposts($i)^/info} + subject=`{sed -n 6p $rposts($i)^/info | awk '{print substr($0,0,50);}'} + # Unicode 00a0 divides the message number from the headline. + # Command input ignores everything after the unicode 00a0. + # These lines may be selected and sent to the prompt + # in order to print the indicated message. + echo ' '$"i' '$"mime' '$"flags' '$"size' '$"date' '$"from' '$"subject + } +} +fn getposts{ ls | grep -e '^[0-9]+$' | sort -n $sort } +fn getr{ + switch($*){ + case ,; echo $posts + case ,*; seq 1 `{echo $* | sed 's/,//g'} + case *,; seq `{echo $* | sed 's/,//g'} $posts($#posts) + case *,*; seq `{echo $* | sed 's/,/ /g'} + case *; echo $* + } +} +fn h{ sed -n $1^p /tmp/h } +fn m{ + if(test $1 -le $#rposts && test -f $rposts($1)^/info){ + subject=`{sed -n 6p $rposts($1)^/info} + if(! ~ $subject FWD:* Fwd:* fwd:*) + subject=(Fwd: $subject) + e -s $"subject -A $rposts($1)^/raw $*(2-) && + flag +a $1 + } + if not + echo !address +} +fn mb{ + mb=$1 + if(test -d /mail/box/$user/$mb || test -d $mb){ + if(! ~ $mb mbox){ + if(~ $mb /mail/fs/*) + mb=`{basename $mb} + if not if(~ $mb /*) + echo open $mb `{basename $mb} >/mail/fs/ctl + if not + echo open /mail/box/$user/$mb $mb >/mail/fs/ctl + mb=`{basename $mb} + } + cd /mail/fs/$mb + dposts=() + y + post=$posts(1) + prompt=$post + } + if not + echo !^$mb does not exist +} +fn printhelp{ +echo 'Commands are of the form [] [args] + := | ',' + := +a reply to sender and recipients +b print the next ten headers +d mark for deletion +e ... enter message (args passed to upas/marshal) +g/regexp/cmd grep headlines for regexp and run cmd on matches +h print message headline (,h for all) +help print this help message +m ... forward mail to address(es) +mb ... change to specified mailbox +p print the processed message +P print the raw message +q quit +r reply to message +s ... store message in specified mailbox +u remove deletion mark +y synchronize with mail box +" print message in quoted form, suitable for reply +|cmd pipe the processed message to a command +||cmd pipe the raw message to a command +!cmd run a command' +} +fn pp{ +if(test $1 -le $#rposts && test -f $rposts($1)^/header){ +{ # Avoid stutter by dumping everything into a file first. + cat $rposts($1)^/header + echo + if(test -d $rposts($1)^/1){ + parts=`{ls -p $rposts($1) | grep -e '^[0-9]+'} + body=1/body + if(test -f $rposts($1)^/1/1/body) + body=1/1/body + } + if not{ + parts=() + body=body + } + type=`{file -m $rposts($1)^/$body} + if(~ $type text/plain) + cat $rposts($1)^/$body + if not if(~ $type text/html){ + hcmd=(htmlfmt -l60 -cutf8 -a $rposts($1)^/$body) + echo !/bin/^$"hcmd + eval $hcmd + echo + echo !--- $rposts($1) $type `{du $rposts($1)^/$body | awk '{print $1}'} [file:///mail/fs/$mb/^$rposts($1)^/$body] # plumb to browser + } + if not{ + disp=`{sed -n 8p $rposts($1)^/info} + file=`{sed -n 9p $rposts($1)^/info} + fakefile $rposts($1) + } + echo + if(! ~ $#parts 0){ + if(! ~ $#parts 1) + parts=$parts(2-) + for(j in $parts){ + type=`{file -m $rposts($1)^/$j/body} + disp=`{sed -n 8p $rposts($1)^/$j/info} + file=`{sed -n 9p $rposts($1)^/$j/info} + fakefile $rposts($1)^/$j + } + parts=() + } +} >/tmp/p + eval $pager /tmp/p + go=1 + r=$1 + post=$1 + prompt=$1 + flag +s $1 +} +if not + echo !address +} +fn P{ + if(test $1 -le $#rposts && test -f $rposts($1)^/rawunix){ + eval $pager $rposts($1)^/rawunix + go=1 + r=$1 + post=$1 + prompt=$1 + flag +s $1 + } + if not + echo !address +} +fn puth{ + flags=`{sed -n 18p $rposts($1)^/info | sed 's/-//g'} + mime=`{ + if(~ `{sed -n 7p $rposts($1)^/info} multipart*) + echo H + } + size=`{sed -n 17p $rposts($1)^/info} + date=`{sed -n 5p $rposts($1)^/info | fmtd} + from=`{sed -n 1p $rposts($1)^/info} + subject=`{sed -n 6p $rposts($1)^/info | awk '{print substr($0,0,50);}'} + { + echo $1 + echo c + # REMEMBER: Unicode 00a0 divides the message number from the headline. + echo ' '^$1^' '$"mime' '$"flags' '$"size' '$"date' '$"from' '$"subject + echo . + echo w + echo q + } | sam -d /tmp/h >/dev/null >[2=1] +} +fn r{ + if(test $1 -le $#rposts && test -f $rposts($1)^/info){ + subject=`{sed -n 6p $rposts($1)^/info} + if(! ~ $subject RE:* Re:* re:*) + subject=(Re: $subject) + e -R $rposts($1) -s $"subject $*(2-) `{sed -n 4p $rposts($1)^/info} && + flag +a $1 + } + if not + echo !address +} +fn s{ + if(test $1 -le $#rposts && test -f $rposts($1)^/raw){ + if(! test -d /mail/box/$user/$2) + echo create $2 >/mail/fs/ctl + /bin/upas/mbappend $2 $rposts($1)^/raw && + flag +S $1 && + echo !saved in $2 + } + if not + echo !address +} +fn u{ + if(test $1 -le $#rposts && test -d $rposts($1)) + flag -D $1 || echo !undelete $1 failed + if not + echo !address + dposts=`{grep -v $1 <{for(j in $dposts){ echo $j }}} +} +fn y{ + go=() + r=$post + if(! ~ $#dposts 0){ + deldposts + dposts=() + } + if(! ~ $q 1){ + rposts=`{getposts} + posts=`{seq 1 $#rposts} + post=$posts(1) + prompt=$post + geth $posts >/tmp/h + if(~ $#msg 0) + echo $#posts messages + } +} +fn yn{ + echo + echo -n $* ' (y, n) ' + yn=`{read} + switch($yn){ + case y n + ; + case * + yn + } +} +fn '"' { pager=cat pp $1 | sed 1d | sed 's/^/> /g' | sed 's/^> >/>>/g' } +fn usage{ + echo usage: $argv0 [ -b ] [ -d ] [ -f mbox ] [ -p msg ] [ -r ] >[1=2] + exit usage +} +while(~ $1 -*){ + switch($1){ + case -b; biff=-b + case -d; debug=1 + case -f; mb=$2; shift + case -p; msg=$2; shift + case -r; sort=(); shift + case *; usage + } + shift +} +if(! ~ $#* 0) + usage +if(! test -f /mail/fs/ctl) + /bin/upas/fs $biff #>[2]/dev/null +if(! test -d /mail/box/$user/$mb && ! test -d $mb){ + echo !^$mb does not exist + exit $mb^' does not exist' +} +mb $mb +if(! ~ $#msg 0){ + for(i in `{seq 1 $#rposts}) + if(~ $msg $rposts($i)) + msg=$posts($i) + pp $msg +} +while(){ + echo -n $"prompt': ' + # Command input ignores everything after unicode 00a0. + rcmd=`{read | sed 's/[ ].*$//g' | sed 's/^([0-9]+)?(,)?([0-9]+)?/& /g'} + switch($rcmd){ + case ,* [0-9]* + r=`{getr $rcmd(1)} + cmd=$rcmd(2-) + if(~ $#cmd 0) + cmd=p + case * + r=$post + cmd=$rcmd + } + switch($cmd){ + case a a' '* + for(i in $r) + r $i $cmd(2-) `{sed -n 2,3p $rposts($i)^/info | sort -n | uniq} + post=$r($#r) + prompt=$post + case b + r=`{seq $r(1) `{echo $r(1)^+10|bc}} + if(test $r($#r) -gt $posts($#posts)) + r=`{seq $r(1) $posts($#posts)} + if(! ~ $#r 0 && test $r(1) -le $posts($#posts)){ + sed -n $r(1)^,$r($#r)^p /tmp/h + post=$r($#r) + prompt=$post + } + if not + echo !address + case d + for(i in $r) + d $i + post=$r($#r) + prompt=$post + case e' '* + e $cmd(2-) + case g/* + regexp=`{echo $cmd | awk -F '/' '{print $2;}'} # BUG: / is stripped from regexp and cmd. + cmd=`{echo $cmd | awk -F '/' '{$1=""; $2=""; print;}'} + r=`{