diff options
author | stanley lieber <stanley.lieber@gmail.com> | 2014-04-01 14:34:29 -0400 |
---|---|---|
committer | stanley lieber <stanley.lieber@gmail.com> | 2014-04-01 14:34:29 -0400 |
commit | 8347075fd940894edcc27e36cb3a21d368c4e606 (patch) | |
tree | 001f7ae487e480757153629b938e684713993390 | |
parent | 5d3d085492010ab1f4900892e000a3c175bcac90 (diff) | |
download | plan9front-8347075fd940894edcc27e36cb3a21d368c4e606.tar.xz |
add newt(1): nntp client for use with nntpfs(4)
-rwxr-xr-x | rc/bin/newt | 246 | ||||
-rw-r--r-- | sys/man/1/newt | 132 |
2 files changed, 378 insertions, 0 deletions
diff --git a/rc/bin/newt b/rc/bin/newt new file mode 100755 index 000000000..f83e96b6b --- /dev/null +++ b/rc/bin/newt @@ -0,0 +1,246 @@ +#!/bin/rc +# bloated, featureful usenet reader for use with nntpfs +rfork en +ramfs +argv0=$0 +if(~ $#editor 0) + editor=hold +group=alt/test +maxposts=30 +mnt=/mnt/news +if(~ $#newtname 0) + newtname=newt@dont-email.me +fn enterpost{ + { + echo From: $"newtname + echo Newsgroups: `{echo $group | sed 's/\//\./g'} + echo Subject: $"subject + echo + } >/tmp/post + eval $editor /tmp/post + cat /tmp/post >$mnt/$group/post +} +fn f { du -a $* | sed 's/^.* //g' } +fn fmtd{ + date=`{cat} + if(! ~ $date(1) [0-9]*) + date=`{nshift $date} + da=$date(1) + 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 + } + if(! ~ $date(3) `{date | awk '{print $6;}'}) + ti=$date(3) + if not + ti=`{echo $date(4) | awk '{print substr($0,0,5);}'} + echo $mo/$da $ti +} +fn geth{ + for(i in $*){ + from=`{awk -F ' ' '{print $3;}' $i/xover} + if(! ~ $#from 0 && ! ~ $#from 1){ + nfrom=`{ + for(i in $from){ + if(~ $i *@*) + echo $i | sed 's/(<|>)//g' + } + } + if(! ~ $#nfrom 0) + from=$nfrom + } + if(! ~ $#from 0){ + date=`{awk -F ' ' '{print $4;}' $i/xover >[2]/dev/null | fmtd} + awk -v date'='$"date -v from'='$from(1) -F ' ' \ + '{print " " $1 " " date " " from " " substr($2,0,50);}' $i/xover >[2]/dev/null + } + if not + echo ' '$"i' nil nil nil' + } +} +fn getposts{ ls | grep -e '^[0-9]+$' | sort -n | tail -$maxposts } +fn k{ + kmnt=`{echo $mnt | sed 's/\//\\\//g'} + f $mnt/$* | + grep -v -e '\/([0-9]+(\/|$)|post$)' | + sed 's/^'$"kmnt'\// g /g' | + sort +} +fn nshift{ shift; echo $* } +fn printhelp{ +echo '[0-9]+ print specified message +b back +e enter message +f jump to first message +g ... go to specified group +h print message headlines +help print this help message +k ... list sub-groups under specified group +l jump to last message +n next +p print message with minimal headers +P print message with full headers +q quit +r reply to message +y synchronize message list with server +" print message in quoted form, suitable for reply +|cmd pipe message body to a command +||cmd pipe raw message to a command +? print debug information' +} +fn printp{ + if(test -d $mnt/$group/$1){ + grep -e '(^From|^Newsgroups|^Subject|^Date)' $1/header + echo + cat $1/body + } + echo + prompt=$group/$1 +} +fn printpp{ + if(test -d $mnt/$group/$1){ + cat $1/article + } + echo + prompt=$group/$1 +} +fn usage{ + echo usage: $argv0 '[ -f newsgroup ] [ -m mountpoint ] [ -p maxposts ]' >[1=2] + exit usage +} +while(~ $1 -*){ + switch($1){ + case -f + group=`{echo $2 | sed 's/\./\//g'} + shift + case -m + mnt=$2 + shift + case -p + maxposts=$2 + shift + case * + usage + } + shift +} +if(! ~ $#* 0) + usage +prompt=$group +if(! test -d $mnt/$group){ + echo !$mnt/$group does not exist >[1=2] + exit +} +builtin cd $mnt/$group +go=() +posts=`{getposts} +geth $posts >/tmp/h +post=$posts(1) +echo $#posts messages +while(){ + echo -n $"prompt': ' + cmd=`{read} + switch($cmd){ + case [0-9]* + post=$cmd(1) + printp $post + case b + if(! ~ $post $posts(1)){ + post=`{echo $post^-1 | bc} + printp $post + } + case e + enterpost + case f + post=$posts(1) + printp $post + case g' '* + ngroup=`{nshift $cmd | sed 's/\./\//g'} + if(test -d $mnt/$ngroup){ + if(grep -s -e '^[0-9]+$' <{ls -p $mnt/$ngroup}){ + group=$ngroup + builtin cd $mnt/$group + go=() + posts=`{getposts} + geth $posts >/tmp/h + post=$posts(1) + prompt=$group + echo $#posts messages + } + if not + echo !$ngroup contains no messages + } + if not + echo !$ngroup does not exist + case h + cat /tmp/h + case help + printhelp + case k + k $group + case k' '* + k `{nshift $cmd | sed 's/\./\//g'} + case l + post=$posts($#posts) + printp $post + case p + printp $post + case p' '* + post=`{nshift $cmd} + printp $post + case P + printpp $post + case P' '* + post=`{nshift $cmd} + printpp $post + case q + exit + case r + if(test -f $mnt/$group/$post/header){ + subject='Re: '^`{grep -e '^Subject: ' $mnt/$group/$post/header | sed 's/^Subject: //g'} + enterpost + } + if not + echo !message missing + case y + posts=`{getposts} + geth $posts >/tmp/h + echo $#posts messages + case '"' + printp $post | sed 1d | sed 's/^/> /g' | sed 's/^> >/>>/g' + case '||'* + cmd=`{echo $"cmd | sed 's/^\|\|//g'} + cat $mnt/$group/$post/article | eval $cmd + case '|'* + cmd=`{echo $"cmd | sed 's/^\|//g'} + cat $mnt/$group/$post/body | eval $cmd + case '?' + echo mnt: $mnt + echo group: $group + echo maxposts: $maxposts + echo posts: $posts + echo post: $post + case n * + if(~ $post $posts(1) && ~ $#go 0){ + go=1 + printp $post + } + if not if(! ~ $post $posts($#posts)){ + go=1 + post=`{echo $post^+1 | bc} + if(test $post -gt $posts($#posts)) + post=$posts($#posts) + printp $post + } + } +} diff --git a/sys/man/1/newt b/sys/man/1/newt new file mode 100644 index 000000000..90afd56ea --- /dev/null +++ b/sys/man/1/newt @@ -0,0 +1,132 @@ +.TH NEWT 1 +.SH NAME +newt \- network news transport protocol (NNTP) client +.SH SYNOPSIS +.B newt +[ +.B -f +.I newsgroup +] [ +.B -m +.I mountpoint +] [ +.B -p +.I maxposts +] +.SH DESCRIPTION +.I Newt +provides an interactive, text-based interface to NNTP +articles served by +.IR nntpfs (4) . +.PP +There are a number of options: +.TP +.B -f +Load the specified newsgroup. Default is +.B alt.test. +.TP +.B -m +Directory where +.I nntpfs +is mounted. Default is +.B /mnt/news. +.TP +.B -p +Number of posts to display, up to and including the most recent post. +.PP +.I Newt +starts by reading the list of messages in the +.I newsgroup, +printing out the number of messages, and then prompting for commands +from standard input. The prompt itself presents the name of the group +and the message number in the form of a file system path relative to the +.I mountpoint. +.PP +The commands are: +.PP +.TP +.I number +Print message +.I number. +.TP +.B b +Print the previous message. +.TP +.B e +Enter a new message, honoring the environment variable +.I editor. +Default is +.IR hold (1) . +.TP +.B f +Jump to the first message in the group. +.TP +.BI g " newsgroup +Change to the specified +.I newsgroup. +The name of a group may be provided in dotted +(\fIalt.test\fR) or path (\fIalt/test\fR) format. +.TP +.B h +Print the disposition, date, sender and subject line +of all messages in the group. These lines are suitable +for selecting and sending to the prompt, in order to +print messages either singly or in aggregate. +.TP +.B help +Print a summary of the available commands. +.TP +.BI k " [newsgroup] +Without an argument, +.I k +walks the directories under the current group +and prints commands suitable for changing to each +available sub-group. When provided with an argument, +it instead walks the directories under the group specified +by the argument. +.TP +.B l +Jump to the last message in the group. +.TP +.B n, or enter key +Print the next message. +.TP +.B p +Print the current message with minimal headers. +.TP +.B P +Print the raw message with full headers. +.TP +.B q +Quit. +.TP +.B r +Reply to the current message. +.TP +.B y +Synchronize message list with the server. +.TP +.BI | command +Run the +.I command +with the message body as standard input. +.TP +.BI || command +Run the +.I command +with the whole message as standard input. +.TP +\fB"\fP +Print the current message in quoted form, suitable for reply. +.SH SOURCE +.B /rc/bin/newt +.SH "SEE ALSO" +.IR nntpfs (4) +.SH BUGS +The list of available newsgroups offered by a given server +may run to many megabytes in size. This complicates +walking the list over a slow Internet connection, and renders +searching all but infeasible. +.SH HISTORY +.I Newt +first appeared in 9front (April, 2014). |