`ctree' - a tiny conference tree (in Bourne shell!)
The WITNESS
bsa at ncoast.UUCP
Tue Sep 25 13:07:49 AEST 1984
I don't expect that this program will win any awards or be widely used,
but it is a curio I wrote that might interest a few people on the net.
After having run a BBS on ncoast for public use, then taking it down
to fix many many bugs in the thing, I got lots of complaints through
the gripe login from people who wanted their BBS back. Since the original
BBS was a conference-oriented type (not as general as CommuniTree but
more so than most in that there was no fixed number of conferences and
anyone could create a new one at any time), I sought a conference-oriented
replacement. This set of shell scripts (and a few C programs) is the
result. Most of it could probably be coded into C, but I didn't feel
like writing a recursive directory descender, so I cheated and used the
find command from the shell.
This beastie is slow, but it works. You might like this thing even if
it's too slow to be practical.
Anyway, here it is, as a shar archive. Being itself a set of shell scripts,
it has been written to autoinstall itself. Just run the archive through
sh and watch it fly. (Put the shar archive in a directory other than
the one in which you want the actual utree to go -- it will work the
other way, but give lots of spurious error messages from cp.) The C
programs are simple and should require no modification; they were coded
in C for speed, not utility. `linelist' miht be a good general utility
as well.
Oh -- one last thing: it was designed under Xenix and uses V7 standard
stuff only. I THINK it will run on anything later than V7, but who knows
for certain until it's been tested?
Enough babbling -- without further ado, I present...
----------------CUT---------------------------------CUT---------------------
: This is a shar archive. Extract with sh not csh.
echo 'sh - indechof.c'
sed 's/^X//' <<'________This_Is_The_END________' >>indechof.c
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
Xstruct stat sb;
Xextern char *index(), *basename();
Xchar *mtimeof();
X
Xmain(argc, argv) char **argv; {
X FILE *f;
X char usagefile[1024], *cp;
X int usage, cnt;
X
X if (argc != 3) {
X fprintf(stderr, "Usage: indechof file indmark\n");
X exit(0);
X }
X sprintf(usagefile, "%s/.users", argv[1]);
X if ((f = fopen(usagefile, "r")) == NULL) {
X fprintf(stderr, "Who?\n");
X exit(-1);
X }
X fscanf(f, "%d", &usage);
X fclose(f);
X if (strcmp(argv[1], argv[2]) == 0) {
X printf("%-.14s\nUsers: %4d Created: %.16s\n\n", basename(argv[1]), usage, mtimeof(argv[1]));
X exit(0);
X }
X cnt = 0, cp = argv[1];
X while (argv[1][cnt] == argv[2][cnt])
X cnt ++, cp ++;
X cnt = 2;
X while ((cp = index(cp + 1, '/')) != NULL)
X cnt += 2;
X printf("%*s%-.14s\nUsers: %4d Created: %.16s\n\n", cnt, "", basename(argv[1]), usage, mtimeof(argv[1]));
X}
X
Xchar *mtimeof(file) char *file; {
X static char timestr[80];
X
X if(stat(file, &sb) < 0)
X return("Never created or modified.");
X sprintf(timestr, "%.16s\n", ctime(&(sb.st_mtime)));
X return(timestr);
X}
X
Xchar *rindex();
X
Xchar *basename(file) char *file; {
X char *f;
X
X return((f = rindex(file, '/')) == NULL? file : f + 1);
X}
________This_Is_The_END________
echo 'sh - linelist.c'
sed 's/^X//' <<'________This_Is_The_END________' >>linelist.c
X#include <stdio.h>
Xmain(argc, argv) char **argv; {
X int lineno;
X FILE *f;
X char line[256];
X
X if (argc != 2)
X f = stdin;
X else if ((f = fopen(argv[1], "r")) == NULL)
X exit(-1);
X lineno = 0;
X while (fgets(line, 256, f) != NULL)
X printf("Line %d:\n%s\n", ++lineno, line);
X fclose(f);
X}
________This_Is_The_END________
echo 'sh - mtimeof.c'
sed 's/^X//' <<'________This_Is_The_END________' >>mtimeof.c
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
Xstruct stat sb;
X
Xmain(argc, argv) char **argv; {
X if (argc != 2) {
X fprintf(stderr, "Usage: mtimeof file\n");
X exit(-1);
X }
X if(stat(argv[1], &sb) < 0) {
X printf("Never created or modified.");
X exit(0);
X }
X printf("%.16s\n", ctime(&(sb.st_mtime)));
X}
________This_Is_The_END________
echo 'sh - utaddto'
sed 's/^X//' <<'________This_Is_The_END________' >>utaddto
X:
X: utaddto - add to a utree conference
X:
X
Xtrap 'stty eofc "^D"; rm /tmp/ut[ab]$$ >/dev/null 2>&1; exit 0' 2
Xtrap '' 15 3
X
Xif [ $# -eq 0 ]
Xthen echo "Missing conference name."
X exit
Xfi
X
XCONF=`echo $1 | tr 'a-z' 'A-Z' | tr -cd 'A-Za-z-_ at 0-9'`
XCDIR=`find $UTREE -name $CONF -print 2>/dev/null | sh -c 'read a junk; echo $a'`
X
Xif [ "$CDIR" = "" ]
Xthen echo "No such conference - $CONF"
X exit
Xfi
X
Xcat <<%%%
X
XEnter the lines of your message; press the ESCAPE key to exit.
X
X%%%
Xstty eofc '^['
Xcat >/tmp/uta$$
Xwhile true
Xdo echo
X echo -n "Editor command (L, C, E, S, A, ?): "
X read cmd junk
X case "$cmd" in
X L | l )
X linelist /tmp/uta$$ ;;
X C | c )
X echo
X echo 'Enter your lines; press ESCAPE to exit.'
X echo
X cat >>/tmp/uta$$ ;;
X E | e )
X while true
X do echo -n "Enter the line # to replace, or ENTER to exit: "
X read cmd junk
X if [ "$cmd" = "" ]
X then break
X fi
X echo "Enter the replacement line, or ENTER to abort:"
X read line
X if [ "$line" != "" ]
X then sed "${cmd}c\\\
X$line\\\
X." </tmp/uta$$ > /tmp/utb$$
X mv /tmp/utb$$ /tmp/uta$$
X fi
X done ;;
X A | a )
X rm /tmp/uta$$
X break ;;
X S | s )
X echo -n "Enter the name of this conference, or ENTER to abort: "
X read conf junk
X if [ "$conf" != "" ]
X then conf=`echo $conf | tr 'a-z' 'A-Z' | tr -cd 'A-Z0-9-_@'`
X newc=`find $UTREE -type d -name $conf -print`
X if [ "$newc" != "" ]
X then echo "Sorry, that name's in use."
X else mkdir $CDIR/$conf
X mv /tmp/uta$$ $CDIR/$conf/.message
X echo 0 >$CDIR/$conf/.users
X break
X fi
X fi ;;
X '?' )
X cat <<%%%
X
XEditor commands
X---------------
XL List message
XE Edit message
XS Save message
XA Abort without saving message
XC Continue entering message
X
X%%%
X echo ;;
X esac
Xdone
Xstty eofc '^D'
Xexit
________This_Is_The_END________
echo 'sh - utbrowse'
sed 's/^X//' <<'________This_Is_The_END________' >>utbrowse
X:
X: utbrowse - conference browse utility for utree
X:
X
Xtrap 'exit 0' 2
Xtrap '' 15 3
X
Xif [ $# -eq 0 ]
Xthen echo "Missing conference name."
X exit
Xfi
X
XCONF=`echo $1 | tr 'a-z' 'A-Z' | tr -cd 'A-Za-z-_ at 0-9'`
XCDIR=`find $UTREE -name $CONF -print 2>/dev/null | sh -c 'read a junk; echo $a'`
X
Xif [ "$CDIR" = "" ]
Xthen echo "No such conference - $CONF"
X exit
Xfi
X
Xcase "$2" in
X"" )
X utcat -b $CDIR
X echo
X echo "Subconferences:"
X echo
X lc $CDIR
X echo ;;
X"C" | "c" | "COMPLETE" | "complete" )
X find $CDIR -type d -exec utcat -b '{}' ';'
X echo ;;
X"A" | "a" | "AFTER" | "after" )
X if [ $# -ne 3 ]
X then echo "Missing days parameter."
X exit
X fi
X find $CDIR -type d -mtime $3 -exec utcat -b '{}' ';'
X echo ;;
X* )
X echo "No such option." ;;
Xesac
Xexit
________This_Is_The_END________
echo 'sh - utcat'
sed 's/^X//' <<'________This_Is_The_END________' >>utcat
X:
X: utcat - display a conference for utree
X: browse option shows the first 2 lines of a conference
X:
X
Xtrap 'exit 0' 2
Xtrap '' 15 3
X
Xif [ $# -eq 0 ]
Xthen echo "Usage: $0 [-b] conference-dir-path"
X exit
Xfi
X
Xif [ "$1" = "-b" ]
Xthen cmd="head -2"
X shift
Xelse cmd=cat
Xfi
X
XUSERS=`cat $1/.users`
XCONF=`basename $1`
X
Xcat <<%%%
X
X*** $CONF *****************************
XCreated: `mtimeof $1` Users: $USERS
X
X%%%
Xexpr $USERS + 1 >$1/.users
Xexec $cmd $1/.message
________This_Is_The_END________
echo 'sh - utindex'
sed 's/^X//' <<'________This_Is_The_END________' >>utindex
X:
X: utindex - index a utree
X:
X
Xtrap 'exit 0' 2
Xtrap '' 15 3
X
Xif [ $# -eq 0 ]
Xthen echo "Missing conference name."
X exit
Xfi
X
XCONF=`echo $1 | tr 'a-z' 'A-Z' | tr -cd 'A-Za-z-_ at 0-9'`
XCDIR=`find $UTREE -name $CONF -print 2>/dev/null | sh -c 'read a junk; echo $a'`
X
Xif [ "$CDIR" = "" ]
Xthen echo "No such conference - $CONF"
X exit
Xfi
X
Xcase "$2" in
X"" )
X indechof $CDIR $CDIR
X echo
X echo "Subconferences:"
X echo
X lc $CDIR
X echo ;;
X"C" | "c" | "COMPLETE" | "complete" )
X find $CDIR -type d -exec indechof '{}' $CDIR ';'
X echo ;;
X"A" | "a" | "AFTER" | "after" )
X if [ $# -ne 3 ]
X then echo "Missing days parameter."
X exit
X fi
X find $CDIR -type d -mtime -$3 -exec indechof '{}' $CDIR ';'
X echo ;;
X* )
X echo "No such option." ;;
Xesac
Xexit
________This_Is_The_END________
echo 'sh - utmake'
sed 's/^X//' <<'________This_Is_The_END________' >>utmake
X
X:
X: Make a utree structure
X:
X
Xecho -n "What directory is to be the root? "
Xread utroot
Xsed "s/%R%/$utroot/" <utree.sh >utree.tmp
Xecho -n "In what directory will the command files reside? "
Xread utpath
Xsed "s/%P%/$utpath/" <utree.tmp >utree
Xrm utree.tmp
Xchmod +x ut*
Xmkdir $utroot $utroot/CONFERENCES
Xecho 0 >$utroot/CONFERENCES/.users
Xcat <<%%% >$utroot/CONFERENCES/.message
XCurrent messages in this Unix Tree are:
X%%%
Xfor file in *.c
Xdo cc $file -o `basename $file .c`
Xdone
XUTREE=$utroot utindex CONFERENCES COMPLETE
Xchmod 777 $utroot/CONFERENCES $utroot/CONFERENCES/.[um]*
Xcp indechof utaddto utread utbrowse utcat utindex linelist mtimeof $utpath
Xcp utree $utpath
Xexit
________This_Is_The_END________
echo 'sh - utread'
sed 's/^X//' <<'________This_Is_The_END________' >>utread
X:
X: utread - conference read utility for utree
X:
X
Xtrap 'exit 0' 2
Xtrap '' 15 3
Xif [ $# -eq 0 ]
Xthen echo "Missing conference name."
X exit
Xfi
X
XCONF=`echo $1 | tr 'a-z' 'A-Z' | tr -cd 'A-Za-z-_ at 0-9'`
XCDIR=`find $UTREE -name $CONF -print 2>/dev/null | sh -c 'read a junk; echo $a'`
X
Xif [ "$CDIR" = "" ]
Xthen echo "No such conference - $CONF"
X exit
Xfi
X
Xcase "$2" in
X"" )
X utcat $CDIR
X echo
X echo "Subconferences:"
X echo
X lc $CDIR
X echo ;;
X"C" | "c" | "COMPLETE" | "complete" )
X find $CDIR -type d -exec utcat '{}' ';'
X echo ;;
X"A" | "a" | "AFTER" | "after" )
X if [ $# -ne 3 ]
X then echo "Missing days parameter."
X exit
X fi
X find $CDIR -type d -mtime -$3 -exec utcat '{}' ';'
X echo ;;
X* )
X echo "No such option." ;;
Xesac
Xexit
________This_Is_The_END________
echo 'sh - utree.sh'
sed 's/^X//' <<'________This_Is_The_END________' >>utree.sh
X:
X: utree - Unix conference tree
X: This program is loosely based on the Conference Tree program by the
X: CommuniTree Group.
X:
X
XUTREE=%R%
XPATH=:/bin:/usr/bin:%P%
Xexport UTREE PATH
XQUIT=n
X
Xtrap '' 15 3 2
Xumask 0
Xcat <<%%%
X
XThe Unix Tree - A Simple Conference-Oriented Communications Package
XPrograms (ut*) by Brandon Allbery, September 18, 1984.
X
X%%%
Xwhile [ $QUIT = n ]
Xdo echo -n "Enter command (R, I, A, B, G, ?): "
X read cmd argA argB argC
X case "$cmd" in
X r | R | read | READ )
X utread $argA $argB $argC ;;
X i | I | index | INDEX )
X utindex $argA $argB $argC ;;
X a | A | addto | ADDTO )
X utaddto $argA $argB $argC ;;
X b | B | browse | BROWSE )
X utbrowse $argA $argB $argC ;;
X g | G | goodbye | GOODBYE )
X QUIT=y ;;
X '?' )
X cat <<%%%
X
XUnix Tree Commands
X------------------
X(Each command may be abbreviated to its first letter.)
X
XREAD Read a conference
XINDEX Index a conference
XADDTO Add to a conference
XBROWSE Browse a conference
XGOODBYE Exit the Unix Tree
X? Print this help message
X
XThe READ, INDEX, and BROWSE commands may use one of the following modifiers:
X
XCOMPLETE Read the specified conference and all subconferences
XAFTER days Read all subconferences less than <days> days old
X
XThese modifiers may be abbreviated to their first letters. Only one may be
Xused in a single command.
X
XExamples:
X
X READ CONFERENCES
X INDEX CONFERENCES AFTER 5
X R CONFERENCES A 15
X
XThe commands may run slowly, as shell scripts are limited in speed. You may
Xexit a command by typing a rubout.
X
X%%%
X echo ;;
X * )
X echo "No such command." ;;
X esac
Xdone
Xecho
Xecho "Goodbye -- call again soon!"
Xexit
________This_Is_The_END________
sh utmake
More information about the Comp.sources.unix
mailing list