rsalz@bbn.com (Rich Salz) (04/26/88)
Submitted-by: Jonathan Payne <jpayne@cs.rochester.edu> Posting-number: Volume 14, Issue 65 Archive-name: jove4.9/part09 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 9 (of 21)." PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f './funcdefs.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./funcdefs.c'\" else echo shar: Extracting \"'./funcdefs.c'\" \(18218 characters\) sed "s/^X//" >'./funcdefs.c' <<'END_OF_FILE' X/*************************************************************************** X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE * X * is provided to you without charge, and with no warranty. You may give * X * away copies of JOVE, including sources, provided that this notice is * X * included in all the files. * X ***************************************************************************/ X X#include "jove.h" X#include "ctype.h" X X#if !defined(TXT_TO_C) extern void X EscPrefix(), X CtlxPrefix(), X MiscPrefix(), X UnbindC(), X ShowVersion(), X WVisSpace(), X#ifdef ANSICODES X AnsiCodes(), X#endif X AppReg(), X Apropos(), X BackChar(), X BList(), X FList(), X BUpList(), X FDownList(), X BSexpr(), X BackWord(), X Bof(), X Bol(), X Bos(), X Bow(), X BindAKey(), X BindMac(), X BufPos(), X#ifdef MSDOS X Buf1Select(), X Buf2Select(), X Buf3Select(), X Buf4Select(), X Buf5Select(), X Buf6Select(), X Buf7Select(), X Buf8Select(), X Buf9Select(), X Buf10Select(), X#endif /* MSDOS */ X CasRegLower(), X CasRegUpper(), X CapChar(), X CapWord(), X LowWord(), X UppWord(), X#ifdef CHDIR X Chdir(), X prCWD(), X prDIRS(), X Pushd(), X Popd(), X#endif X prCTIME(), X ChrToOct(), X ClAndRedraw(), X#ifndef MAC X MakeErrors(), X#endif X CopyRegion(), X BufSelect(), X DelBlnkLines(), X DelNChar(), X DelNWord(), X OneWindow(), X DelPChar(), X DelPWord(), X DelReg(), X KillSome(), X DelWtSpace(), X DelCurWindow(), X KeyDesc(), X Digit(), X Digit0(), X Digit1(), X Digit2(), X Digit3(), X Digit4(), X Digit5(), X Digit6(), X Digit7(), X Digit8(), X Digit9(), X DescBindings(), X DescCom(), X Eof(), X Eol(), X Eos(), X Eow(), X ForPara(), X BackPara(), X BufErase(), X PtToMark(), X Extend(), X ExecMacro(), X RunMacro(), X Leave(), X FindFile(), X WindFind(), X FindTag(), X FDotTag(), X ToIndent(), X ForChar(), X FSexpr(), X ForWord(), X TimesFour(), X GoLine(), X GrowWindow(), X IncFSearch(), X IncRSearch(), X InsFile(), X Justify(), X RegJustify(), X SetLMargin(), X SetRMargin(), X BufKill(), X KillBos(), X KillEos(), X KillEOL(), X KillExpr(), X BufList(), X NotModified(), X NameMac(), X DelMacro(), X Newline(), X OpenLine(), X LineAI(), X#ifndef MAC X ShowErr(), X NextError(), X#endif /* MAC */ X#ifdef MSDOS X PageScrollUp(), X PageScrollDown(), X#endif /* MSDOS */ X#ifndef MAC X PrevError(), X#endif /* MAC */ X NextLine(), X NextPage(), X NextWindow(), X Recur(), X PopMark(), X PageNWind(), X Tab(), X DoParen(), X#ifndef MAC X ParseAll(), X#endif X#ifdef SPELL X SpelWords(), X#endif X#ifdef JOB_CONTROL X PauseJove(), X#endif X PrevLine(), X PrevPage(), X PrevWindow(), X#ifndef MAC X Push(), X#endif X RegReplace(), X QRepSearch(), X QuotChar(), X ReadFile(), X DefKBDMac(), X RedrawDisplay(), X ReNamBuf(), X RepSearch(), X DownScroll(), X UpScroll(), X ForSearch(), X FSrchND(), X RevSearch(), X RSrchND(), X SelfInsert(), X SetVar(), X SetMark(), X#ifndef MAC X ShellCom(), X ShNoBuf(), X Shtypeout(), X ShToBuf(), X#endif X ShrWindow(), X Source(), X#ifdef SPELL X SpelBuffer(), X#endif X SplitWind(), X GotoWind(), X Remember(), X Forget(), X StrLength(), X TransChar(), X TransLines(), X SaveFile(), X WtModBuf(), X WriteFile(), X WriteMacs(), X WrtReg(), X Yank(), X YankPop(), PrVar(), X#ifndef MAC X FilterRegion(), X#endif X WNumLines(), X#ifdef IPROCS X ShellProc(), X ProcInt(), X ProcQuit(), X ProcKill(), X# ifndef PIPEPROCS X ProcEof(), X ProcStop(), X ProcCont(), X ProcDStop(), X# endif X ProcSendData(), X ProcNewline(), X ProcList(), X ProcBind(), X Iprocess(), X#endif X X#ifdef LISP X GSexpr(), /* Grind S Expression. */ X AddSpecial(), /* add lisp special form */ X#endif X CAutoExec(), X MAutoExec(), X X DefMAbbrev(), X DefGAbbrev(), X SaveAbbrevs(), X RestAbbrevs(), X EditAbbrevs(), X BindMtoW(), X X#ifdef CMT_FMT X Comment(), X#endif X X ScrollLeft(), X ScrollRight(), X MacInter(); /* This is the last one. */ X X X#ifdef MAC X# define WIRED_CMD(c) c,'\0','\0' /* for About Jove... */ X#else X# define WIRED_CMD(c) c X#endif /* MAC */ X X#else /* TXT_TO_C */ X X#ifdef MAC X# define WIRED_CMD(c) 0,'\0','\0' X#else X# define WIRED_CMD(c) 0 X#endif X#endif /* TXT_TO_C */ X struct cmd commands[] = { X#ifdef LISP X FUNCTION, "add-lisp-special", WIRED_CMD(AddSpecial), X#endif X#ifdef ANSICODES X FUNCTION, "ansi-codes", WIRED_CMD(AnsiCodes), X#endif X FUNCTION, "append-region", WIRED_CMD(AppReg), X FUNCTION, "apropos", WIRED_CMD(Apropos), X FUNCTION, "auto-execute-command", WIRED_CMD(CAutoExec), X FUNCTION, "auto-execute-macro", WIRED_CMD(MAutoExec), X DefMinor(Fill), "auto-fill-mode", WIRED_CMD(0), X DefMinor(Indent), "auto-indent-mode", WIRED_CMD(0), X FUNCTION, "backward-character", WIRED_CMD(BackChar), X FUNCTION, "backward-list", WIRED_CMD(BList), X FUNCTION, "backward-paragraph", WIRED_CMD(BackPara), X FUNCTION, "backward-s-expression", WIRED_CMD(BSexpr), X FUNCTION, "backward-sentence", WIRED_CMD(Bos), X FUNCTION, "backward-up-list", WIRED_CMD(BUpList), X FUNCTION, "backward-word", WIRED_CMD(BackWord), X FUNCTION, "begin-kbd-macro", WIRED_CMD(Remember), X FUNCTION, "beginning-of-file", WIRED_CMD(Bof), X FUNCTION, "beginning-of-line", WIRED_CMD(Bol), X FUNCTION, "beginning-of-window", WIRED_CMD(Bow), X FUNCTION, "bind-to-key", WIRED_CMD(BindAKey), X FUNCTION, "bind-macro-to-key", WIRED_CMD(BindMac), X#ifdef ABBREV X FUNCTION, "bind-macro-to-word-abbrev", WIRED_CMD(BindMtoW), X#endif X FUNCTION, "buffer-position", WIRED_CMD(BufPos), X DefMajor(CMODE), "c-mode", WIRED_CMD(0), X FUNCTION, "case-character-capitalize", WIRED_CMD(CapChar), X FUNCTION, "case-region-lower", WIRED_CMD(CasRegLower), X FUNCTION, "case-region-upper", WIRED_CMD(CasRegUpper), X FUNCTION, "case-word-capitalize", WIRED_CMD(CapWord), X FUNCTION, "case-word-lower", WIRED_CMD(LowWord), X FUNCTION, "case-word-upper", WIRED_CMD(UppWord), X FUNCTION, "character-to-octal-insert", WIRED_CMD(ChrToOct), X#ifdef CHDIR X FUNCTION, "cd", WIRED_CMD(Chdir), X#endif X FUNCTION, "clear-and-redraw", WIRED_CMD(ClAndRedraw), X#ifndef MAC X FUNCTION, "compile-it", WIRED_CMD(MakeErrors), X#endif X#ifdef IPROCS X# ifndef PIPEPROCS X# ifdef TIOCSLTC X FUNCTION, "continue-process", WIRED_CMD(ProcCont), X# endif X# endif X#endif X FUNCTION, "copy-region", WIRED_CMD(CopyRegion), X#ifndef MAC X FUNCTION, "current-error", WIRED_CMD(ShowErr), X#endif X FUNCTION, "date", WIRED_CMD(prCTIME), X#ifdef ABBREV X FUNCTION, "define-global-word-abbrev", WIRED_CMD(DefGAbbrev), X FUNCTION, "define-mode-word-abbrev", WIRED_CMD(DefMAbbrev), X#endif X FUNCTION, "define-macro", WIRED_CMD(DefKBDMac), X FUNCTION, "delete-blank-lines", WIRED_CMD(DelBlnkLines), X FUNCTION, "delete-buffer", WIRED_CMD(BufKill), X FUNCTION, "delete-macro", WIRED_CMD(DelMacro), X FUNCTION, "delete-next-character", WIRED_CMD(DelNChar), X FUNCTION, "delete-other-windows", WIRED_CMD(OneWindow), X FUNCTION, "delete-previous-character", WIRED_CMD(DelPChar), X FUNCTION, "delete-white-space", WIRED_CMD(DelWtSpace), X FUNCTION, "delete-current-window", WIRED_CMD(DelCurWindow), X FUNCTION, "describe-bindings", WIRED_CMD(DescBindings), X FUNCTION, "describe-command", WIRED_CMD(DescCom), X FUNCTION, "describe-key", WIRED_CMD(KeyDesc), X FUNCTION, "describe-variable", WIRED_CMD(DescCom), X FUNCTION, "digit", WIRED_CMD(Digit), X FUNCTION, "digit-1", WIRED_CMD(Digit1), X FUNCTION, "digit-2", WIRED_CMD(Digit2), X FUNCTION, "digit-3", WIRED_CMD(Digit3), X FUNCTION, "digit-4", WIRED_CMD(Digit4), X FUNCTION, "digit-5", WIRED_CMD(Digit5), X FUNCTION, "digit-6", WIRED_CMD(Digit6), X FUNCTION, "digit-7", WIRED_CMD(Digit7), X FUNCTION, "digit-8", WIRED_CMD(Digit8), X FUNCTION, "digit-9", WIRED_CMD(Digit9), X FUNCTION, "digit-0", WIRED_CMD(Digit0), X#ifdef CHDIR X FUNCTION, "dirs", WIRED_CMD(prDIRS), X#endif X FUNCTION, "down-list", WIRED_CMD(FDownList), X#ifdef IPROCS X# ifndef PIPEPROCS X# ifdef TIOCSLTC X FUNCTION, "dstop-process", WIRED_CMD(ProcDStop), X# endif X# endif X#endif X#ifdef ABBREV X FUNCTION, "edit-word-abbrevs", WIRED_CMD(EditAbbrevs), X#endif X FUNCTION, "end-kbd-macro", WIRED_CMD(Forget), X FUNCTION, "end-of-file", WIRED_CMD(Eof), X FUNCTION, "end-of-line", WIRED_CMD(Eol), X FUNCTION, "end-of-window", WIRED_CMD(Eow), X#ifdef IPROCS X# ifndef PIPEPROCS X FUNCTION, "eof-process", WIRED_CMD(ProcEof), X# endif X#endif X FUNCTION, "erase-buffer", WIRED_CMD(BufErase), X FUNCTION, "exchange-point-and-mark", WIRED_CMD(PtToMark), X FUNCTION, "execute-named-command", WIRED_CMD(Extend), X FUNCTION, "execute-kbd-macro", WIRED_CMD(ExecMacro), X FUNCTION, "execute-macro", WIRED_CMD(RunMacro), X FUNCTION, "exit-jove", WIRED_CMD(Leave), X#ifdef CMT_FMT X FUNCTION, "fill-comment", WIRED_CMD(Comment), X#endif /* CMT_FMT */ X FUNCTION, "fill-paragraph", WIRED_CMD(Justify), X FUNCTION, "fill-region", WIRED_CMD(RegJustify), X#ifndef MAC X FUNCTION, "filter-region", WIRED_CMD(FilterRegion), X#endif X FUNCTION, "find-file", WIRED_CMD(FindFile), X FUNCTION, "find-tag", WIRED_CMD(FindTag), X FUNCTION, "find-tag-at-point", WIRED_CMD(FDotTag), X FUNCTION, "first-non-blank", WIRED_CMD(ToIndent), X FUNCTION, "forward-character", WIRED_CMD(ForChar), X FUNCTION, "forward-list", WIRED_CMD(FList), X FUNCTION, "forward-paragraph", WIRED_CMD(ForPara), X FUNCTION, "forward-s-expression", WIRED_CMD(FSexpr), X FUNCTION, "forward-sentence", WIRED_CMD(Eos), X FUNCTION, "forward-word", WIRED_CMD(ForWord), X DefMajor(FUNDAMENTAL), "fundamental-mode", WIRED_CMD(0), X FUNCTION, "gather-numeric-argument", WIRED_CMD(TimesFour), X#ifdef LISP X FUNCTION, "grind-s-expr", WIRED_CMD(GSexpr), X#endif X FUNCTION, "goto-line", WIRED_CMD(GoLine), X FUNCTION, "goto-window-with-buffer", WIRED_CMD(GotoWind), X FUNCTION, "grow-window", WIRED_CMD(GrowWindow), X FUNCTION, "handle-tab", WIRED_CMD(Tab), X FUNCTION, "i-search-forward", WIRED_CMD(IncFSearch), X FUNCTION, "i-search-reverse", WIRED_CMD(IncRSearch), X FUNCTION, "insert-file", WIRED_CMD(InsFile), X#ifdef IPROCS X FUNCTION, "interrupt-process", WIRED_CMD(ProcInt), X FUNCTION, "i-shell-command", WIRED_CMD(Iprocess), X#endif X FUNCTION, "kill-next-word", WIRED_CMD(DelNWord), X FUNCTION, "kill-previous-word", WIRED_CMD(DelPWord), X#ifdef IPROCS X FUNCTION, "kill-process", WIRED_CMD(ProcKill), X#endif X FUNCTION, "kill-region", WIRED_CMD(DelReg), X FUNCTION, "kill-s-expression", WIRED_CMD(KillExpr), X FUNCTION, "kill-some-buffers", WIRED_CMD(KillSome), X FUNCTION, "kill-to-beginning-of-sentence", WIRED_CMD(KillBos), X FUNCTION, "kill-to-end-of-line", WIRED_CMD(KillEOL), X FUNCTION, "kill-to-end-of-sentence", WIRED_CMD(KillEos), X FUNCTION, "left-margin-here", WIRED_CMD(SetLMargin), X#ifdef LISP X DefMajor(LISPMODE), "lisp-mode", WIRED_CMD(0), X#endif X FUNCTION, "list-buffers", WIRED_CMD(BufList), X#ifdef IPROCS X FUNCTION, "list-processes", WIRED_CMD(ProcList), X#endif X FUNCTION, "make-buffer-unmodified", WIRED_CMD(NotModified), X FUNCTION, "make-macro-interactive", WIRED_CMD(MacInter), X FUNCTION, "name-kbd-macro", WIRED_CMD(NameMac), X FUNCTION, "newline", WIRED_CMD(Newline), X FUNCTION, "newline-and-backup", WIRED_CMD(OpenLine), X FUNCTION, "newline-and-indent", WIRED_CMD(LineAI), X#ifndef MAC X FUNCTION, "next-error", WIRED_CMD(NextError), X#endif X FUNCTION, "next-line", WIRED_CMD(NextLine), X FUNCTION, "next-page", WIRED_CMD(NextPage), X FUNCTION, "next-window", WIRED_CMD(NextWindow), X FUNCTION, "number-lines-in-window", WIRED_CMD(WNumLines), X DefMinor(OverWrite), "over-write-mode", WIRED_CMD(0), X FUNCTION, "page-next-window", WIRED_CMD(PageNWind), X FUNCTION, "paren-flash", WIRED_CMD(DoParen), X#ifndef MAC X FUNCTION, "parse-errors", WIRED_CMD(ErrParse), X#endif X#ifdef SPELL X FUNCTION, "parse-spelling-errors-in-buffer", WIRED_CMD(SpelWords), X#endif X#ifdef JOB_CONTROL X FUNCTION, "pause-jove", WIRED_CMD(PauseJove), X#else X# ifndef MAC X FUNCTION, "pause-jove", WIRED_CMD(Push), X# endif X#endif X FUNCTION, "pop-mark", WIRED_CMD(PopMark), X#ifdef CHDIR X FUNCTION, "popd", WIRED_CMD(Popd), X#endif X FUNCTION, "prefix-1", WIRED_CMD(EscPrefix), X FUNCTION, "prefix-2", WIRED_CMD(CtlxPrefix), X FUNCTION, "prefix-3", WIRED_CMD(MiscPrefix), X#ifndef MAC X FUNCTION, "previous-error", WIRED_CMD(PrevError), X#endif X FUNCTION, "previous-line", WIRED_CMD(PrevLine), X FUNCTION, "previous-page", WIRED_CMD(PrevPage), X FUNCTION, "previous-window", WIRED_CMD(PrevWindow), X FUNCTION, "print", WIRED_CMD(PrVar), X#ifdef IPROCS X FUNCTION, "process-bind-to-key", WIRED_CMD(ProcBind), X FUNCTION, "process-newline", WIRED_CMD(ProcNewline), X FUNCTION, "process-send-data-no-return", WIRED_CMD(ProcSendData), X#endif X#ifndef MAC X FUNCTION, "push-shell", WIRED_CMD(Push), X#endif X#ifdef CHDIR X FUNCTION, "pushd", WIRED_CMD(Pushd), X FUNCTION, "pwd", WIRED_CMD(prCWD), X#endif X FUNCTION, "query-replace-string", WIRED_CMD(QRepSearch), X#ifdef IPROCS X FUNCTION, "quit-process", WIRED_CMD(ProcQuit), X#endif X FUNCTION, "quoted-insert", WIRED_CMD(QuotChar), X#ifdef ABBREV X FUNCTION, "read-word-abbrev-file", WIRED_CMD(RestAbbrevs), X#endif X FUNCTION, "redraw-display", WIRED_CMD(RedrawDisplay), X FUNCTION, "recursive-edit", WIRED_CMD(Recur), X FUNCTION, "rename-buffer", WIRED_CMD(ReNamBuf), X FUNCTION, "replace-in-region", WIRED_CMD(RegReplace), X FUNCTION, "replace-string", WIRED_CMD(RepSearch), X FUNCTION, "right-margin-here", WIRED_CMD(SetRMargin), X FUNCTION, "save-file", WIRED_CMD(SaveFile), X FUNCTION, "scroll-down", WIRED_CMD(DownScroll), X FUNCTION, "scroll-left", WIRED_CMD(ScrollLeft), X#ifdef MSDOS X FUNCTION, "scroll-next-page", WIRED_CMD(PageScrollUp), X FUNCTION, "scroll-previous-page", WIRED_CMD(PageScrollDown), X#endif /* MSDOS */ X FUNCTION, "scroll-right", WIRED_CMD(ScrollRight), X FUNCTION, "scroll-up", WIRED_CMD(UpScroll), X FUNCTION, "search-forward", WIRED_CMD(ForSearch), X FUNCTION, "search-forward-nd", WIRED_CMD(FSrchND), X FUNCTION, "search-reverse", WIRED_CMD(RevSearch), X FUNCTION, "search-reverse-nd", WIRED_CMD(RSrchND), X FUNCTION, "select-buffer", WIRED_CMD(BufSelect), X#ifdef MSDOS X FUNCTION, "select-buffer-1", WIRED_CMD(Buf1Select), X FUNCTION, "select-buffer-2", WIRED_CMD(Buf2Select), X FUNCTION, "select-buffer-3", WIRED_CMD(Buf3Select), X FUNCTION, "select-buffer-4", WIRED_CMD(Buf4Select), X FUNCTION, "select-buffer-5", WIRED_CMD(Buf5Select), X FUNCTION, "select-buffer-6", WIRED_CMD(Buf6Select), X FUNCTION, "select-buffer-7", WIRED_CMD(Buf7Select), X FUNCTION, "select-buffer-8", WIRED_CMD(Buf8Select), X FUNCTION, "select-buffer-9", WIRED_CMD(Buf9Select), X FUNCTION, "select-buffer-10", WIRED_CMD(Buf10Select), X#endif /* MSDOS */ X FUNCTION, "self-insert", WIRED_CMD(SelfInsert), X FUNCTION, "set", WIRED_CMD(SetVar), X FUNCTION, "set-mark", WIRED_CMD(SetMark), X#ifdef IPROCS /* for GNU compatibility */ X FUNCTION, "shell", WIRED_CMD(ShellProc), X#endif X#ifndef MAC X FUNCTION, "shell-command", WIRED_CMD(ShellCom), X FUNCTION, "shell-command-no-buffer", WIRED_CMD(ShNoBuf), X FUNCTION, "shell-command-to-buffer", WIRED_CMD(ShToBuf), X FUNCTION, "shell-command-with-typeout", WIRED_CMD(Shtypeout), X#endif X DefMinor(ShowMatch), "show-match-mode", WIRED_CMD(0), X FUNCTION, "shrink-window", WIRED_CMD(ShrWindow), X FUNCTION, "source", WIRED_CMD(Source), X#ifdef SPELL X FUNCTION, "spell-buffer", WIRED_CMD(SpelBuffer), X#endif X FUNCTION, "split-current-window", WIRED_CMD(SplitWind), X FUNCTION, "start-remembering", WIRED_CMD(Remember), X#ifdef IPROCS X# ifndef PIPEPROCS X FUNCTION, "stop-process", WIRED_CMD(ProcStop), X# endif X#endif X FUNCTION, "stop-remembering", WIRED_CMD(Forget), X FUNCTION, "string-length", WIRED_CMD(StrLength), X#ifdef JOB_CONTROL X FUNCTION, "suspend-jove", WIRED_CMD(PauseJove), X#endif X DefMajor(TEXT), "text-mode", WIRED_CMD(0), X FUNCTION, "transpose-characters", WIRED_CMD(TransChar), X FUNCTION, "transpose-lines", WIRED_CMD(TransLines), X FUNCTION, "unbind-key", WIRED_CMD(UnbindC), X FUNCTION, "version", WIRED_CMD(ShowVersion), X FUNCTION, "visible-spaces-in-window", WIRED_CMD(WVisSpace), X FUNCTION, "visit-file", WIRED_CMD(ReadFile), X FUNCTION, "window-find", WIRED_CMD(WindFind), X#ifdef ABBREV X DefMinor(Abbrev), "word-abbrev-mode", WIRED_CMD(0), X FUNCTION, "write-word-abbrev-file", WIRED_CMD(SaveAbbrevs), X#endif X FUNCTION, "write-file", WIRED_CMD(WriteFile), X FUNCTION, "write-macros-to-file", WIRED_CMD(WriteMacs), X FUNCTION, "write-modified-files", WIRED_CMD(WtModBuf), X FUNCTION, "write-region", WIRED_CMD(WrtReg), X FUNCTION, "yank", WIRED_CMD(Yank), X FUNCTION, "yank-pop", WIRED_CMD(YankPop), X FUNCTION, 0, 0 X}; X X#ifndef TXT_TO_C data_obj * findcom(prompt) char *prompt; X{ X /* This is for faster startup. This just reads until a space or a X tab or a newline character is reached, and then does a X semi-hashed lookup on that string. This should be much faster X than initializing the minibuffer for each line. */ X if (InJoverc) { X char cmdbuf[128]; X register struct cmd *cmd; X register char *cp = cmdbuf; X#if !(defined(IBMPC) || defined(MAC)) X register int c; X#else X int c; X#endif X struct cmd *which; X int cmdlen, X found = 0; X static struct cmd *cmdhash[26]; X static int beenhere = NO; X X/* special case for prefix commands--only upper case ones */ X#define hash(c) (c - 'a') X X /* initialize the hash table */ X if (beenhere == NO) { X int lastc = 0; X X for (cmd = commands; cmd->Name != 0; cmd++) X if (lastc != cmd->Name[0]) { X lastc = cmd->Name[0]; X cmdhash[hash(lastc)] = cmd; X } X beenhere = YES; X } X#ifdef MAC X menus_off(); /* Block menu choices during input */ X#endif X /* gather the cmd name */ X while (((c = getch()) != EOF) && !index(" \t\r\n", c)) { X#if (defined(IBMPC) || defined(MAC)) X lower(&c); X#else X if (isupper(c)) X c = tolower(c); X#endif X *cp++ = c; X } X if (c == EOF) X return 0; X *cp = '\0'; X cmdlen = cp - cmdbuf; X if (cmdlen == 0) X return 0; X X /* look it up (in the reduced search space) */ X if (islower(cmdbuf[0])) X for (cmd = cmdhash[hash(cmdbuf[0])]; cmd != 0 && cmd->Name[0] == cmdbuf[0]; cmd++) { X if (strncmp(cmd->Name, cmdbuf, cmdlen) == 0) { X if (strcmp(cmd->Name, cmdbuf) == 0) X return (data_obj *) cmd; X found += 1; X which = cmd; X } X } X if (found > 1) X complain("[\"%s\" ambiguous]", cmdbuf); X else if (found == 0) X complain("[\"%s\" unknown]", cmdbuf); X else X return (data_obj *) which; X } else { X static char *strings[(sizeof commands) / sizeof (commands[0])]; X static int beenhere = NO; X register int com; X X if (beenhere == NO) { X register char **strs = strings; X register struct cmd *c; X X for (c = commands; c->Name != 0; c++) X *strs++ = c->Name; X *strs = 0; X beenhere = YES; X } X X if ((com = complete(strings, prompt, CASEIND)) < 0) X return 0; X return (data_obj *) &commands[com]; X } X /* NOTREACHED */ X} X#endif END_OF_FILE if test 18218 -ne `wc -c <'./funcdefs.c'`; then echo shar: \"'./funcdefs.c'\" unpacked with wrong size! fi # end of './funcdefs.c' fi if test -f './proc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./proc.c'\" else echo shar: Extracting \"'./proc.c'\" \(18101 characters\) sed "s/^X//" >'./proc.c' <<'END_OF_FILE' X/*************************************************************************** X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE * X * is provided to you without charge, and with no warranty. You may give * X * away copies of JOVE, including sources, provided that this notice is * X * included in all the files. * X ***************************************************************************/ X X#include "jove.h" X#include "io.h" X#include "termcap.h" X X#include <signal.h> X#include <varargs.h> X X#ifdef MSDOS X#include <io.h> X#include <process.h> X#endif X X X#ifdef LINT_ARGS private void X DoShell(char *, char *), X com_finish(int, char *), X toerror(int, int), X closepipe(void); X private int X okay_error(void), X openforpipe(void), X reopenforpipe(void); X private struct error X * AddError(struct error *, Line *, Buffer *, Line *, int); X#else private void X DoShell(), X com_finish(), X toerror(), X closepipe(); X private int X openforpipe(), X okay_error(), X reopenforpipe(); X private struct error X * AddError(); X#endif X X X/* This disgusting RE search string parses output from the GREP X family, from the pdp11 compiler, pcc, and lint. Jay (HACK) X Fenlasen changed this to work for the lint errors. */ char ErrFmtStr[256] = "^\\{\",\\}\\([^:\"( \t]*\\)\\{\"\\, line ,:,(\\} *\\([0-9][0-9]*\\)[:)]\ X\\|:: *\\([^(]*\\)(\\([0-9]*\\))$\ X\\|( \\([^(]*\\)(\\([0-9]*\\)) ),"; X struct error { X Buffer *er_buf; /* Buffer error is in */ X Line *er_mess, /* Actual error message */ X *er_text; /* Actual error */ X int er_char; /* char pos of error */ X struct error *er_prev, /* List of errors */ X *er_next; X}; X struct error *cur_error = 0, X *errorlist = 0; Buffer *perr_buf = 0; /* Buffer with error messages */ X int WtOnMk = 1; /* Write the modified files when we make */ X X/* Add an error to the end of the list of errors. This is used for X parse-{C,LINT}-errors and for the spell-buffer command */ X private struct error * AddError(laste, errline, buf, line, charpos) struct error *laste; Line *errline, X *line; Buffer *buf; X{ X struct error *new = (struct error *) emalloc(sizeof *new); X X new->er_prev = laste; X if (laste) X laste->er_next = new; X else { X if (errorlist) /* Free up old errors */ X ErrFree(); X cur_error = errorlist = new; X } X laste = new; X new->er_next = 0; X new->er_buf = buf; X new->er_text = line; X new->er_char = charpos; X new->er_mess = errline; X X return new; X} X X/* Parse errors of the form specified in ErrFmtStr in the current X buffer. Do a show error of the first error. This is neat because this X will work for any kind of output that prints a file name and a line X number on the same line. */ X void ErrParse() X{ X Bufpos *bp; X char fname[FILESIZE], X lineno[10], X REbuf[256], X *REalts[10]; X int lnum, X last_lnum = -1; X struct error *ep = 0; X Buffer *buf, X *lastb = 0; X Line *err_line; X X ErrFree(); /* This is important! */ X ToFirst(); X perr_buf = curbuf; X REcompile(ErrFmtStr, 1, REbuf, REalts); X /* Find a line with a number on it. */ X while (bp = docompiled(FORWARD, REbuf, REalts)) { X SetDot(bp); X putmatch(1, fname, sizeof fname); X putmatch(2, lineno, sizeof lineno); X buf = do_find((Window *) 0, fname, 1); X if (buf != lastb) { X lastb = buf; X last_lnum = -1; /* signals new file */ X err_line = buf->b_first; X } X (void) chr_to_int(lineno, 10, NO, &lnum); X if (lnum == last_lnum) /* one error per line is nicer */ X continue; X if (last_lnum == -1) X last_lnum = 1; /* that's where we really are */ X err_line = next_line(err_line, lnum - last_lnum); X ep = AddError(ep, curline, buf, err_line, 0); X last_lnum = lnum; X } X if (cur_error != 0) X ShowErr(); X} X X/* Free up all the errors */ X void ErrFree() X{ X register struct error *ep; X X for (ep = errorlist; ep != 0; ep = ep->er_next) X free((char *) ep); X errorlist = cur_error = 0; X} X X/* Internal next error sets cur_error to the next error, taking the X argument count, supplied by the user, into consideration. */ X private char errbounds[] = "You're at the %s error.", X noerrs[] = "No errors!"; X private void toerror(forward, num) X{ X register struct error *e = cur_error; X X if (e == 0) X complain(noerrs); X if ((forward && (e->er_next == 0)) || X (!forward && (e->er_prev == 0))) X complain(errbounds, forward ? "last" : "first"); X X while (--num >= 0) { X if ((e = forward ? e->er_next : e->er_prev) == 0) X break; X cur_error = e; X } X} X void NextError() X{ X ToError(1); X} X void PrevError() X{ X ToError(0); X} X private int okay_error() X{ X return ((inlist(perr_buf->b_first, cur_error->er_mess)) && X (inlist(cur_error->er_buf->b_first, cur_error->er_text))); X} X X/* Go the the next error, if there is one. Put the error buffer in X one window and the buffer with the error in another window. X It checks to make sure that the error actually exists. */ X void ToError(forward) X{ X do { X toerror(forward, arg_value()); X } while (!okay_error()); X ShowErr(); X} X int EWSize = 20; /* percentage of screen the error window X should be */ X void set_wsize(wsize) int wsize; X{ X wsize = (LI * wsize) / 100; X if (wsize >= 1 && !one_windp()) X WindSize(curwind, wsize - (curwind->w_height - 1)); X} X X/* Show the current error, i.e. put the line containing the error message X in one window, and the buffer containing the actual error in another X window. */ X void ShowErr() X{ X Window *err_wind, X *buf_wind; X X if (cur_error == 0) X complain(noerrs); X if (!okay_error()) { X rbell(); X return; X } X err_wind = windbp(perr_buf); X buf_wind = windbp(cur_error->er_buf); X X if (err_wind && !buf_wind) { X SetWind(err_wind); X pop_wind(cur_error->er_buf->b_name, NO, -1); X buf_wind = curwind; X } else if (!err_wind && buf_wind) { X SetWind(buf_wind); X pop_wind(perr_buf->b_name, NO, -1); X err_wind = curwind; X } else if (!err_wind && !buf_wind) { X pop_wind(perr_buf->b_name, NO, -1); X err_wind = curwind; X pop_wind(cur_error->er_buf->b_name, NO, -1); X buf_wind = curwind; X } X X /* Put the current error message at the top of its Window */ X SetWind(err_wind); X SetLine(cur_error->er_mess); X SetTop(curwind, (curwind->w_line = cur_error->er_mess)); X set_wsize(EWSize); X X /* now go to the the line with the error in the other window */ X SetWind(buf_wind); X DotTo(cur_error->er_text, cur_error->er_char); X} X char ShcomBuf[128] = {0}; X X/* Make a buffer name given the command `command', i.e. "fgrep -n foo *.c" X will return the buffer name "fgrep". */ X char * MakeName(command) char *command; X{ X static char bufname[50]; X register char *cp = bufname, X c; X X while ((c = *command++) && (c == ' ' || c == '\t')) X ; X do X *cp++ = c; X while ((c = *command++) && (c != ' ' && c != '\t')); X *cp = 0; X strcpy(bufname, basename(bufname)); X X return bufname; X} X X/* Run make, first writing all the modified buffers (if the WtOnMk flag is X non-zero), parse the errors, and go the first error. */ X char make_cmd[128] = "make"; X void MakeErrors() X{ X Window *old = curwind; X int status, X compilation; X X if (WtOnMk) X put_bufs(0); X /* When we're not doing make or cc (i.e., the last command X was probably a grep or something) and the user just types X C-X C-E, he probably (possibly, hopefully, usually (in my X case)) doesn't want to do the grep again but rather wants X to do a make again; so we ring the bell and insert the X default command and let the person decide. */ X X compilation = (sindex("make", make_cmd) || sindex("cc", make_cmd)); X if (is_an_arg() || !compilation) { X if (!compilation) { X rbell(); X Inputp = make_cmd; /* insert the default for the user */ X } X null_ncpy(make_cmd, ask(make_cmd, "Compilation command: "), X sizeof (make_cmd) - 1); X } X status = UnixToBuf(MakeName(make_cmd), YES, EWSize, YES, Shell, ShFlags, make_cmd, (char *) 0); X com_finish(status, make_cmd); X X ErrParse(); X X if (!cur_error) X SetWind(old); X} X X#ifdef SPELL X void SpelBuffer() X{ X char *Spell = "Spell", X com[100]; X Window *savewp = curwind; X X put_bufs(0); X sprintf(com, "spell %s", curbuf->b_fname); X (void) UnixToBuf(Spell, YES, EWSize, YES, Shell, ShFlags, com, (char *) 0); X message("[Delete the irrelevant words and then type C-X C-C]"); X ToFirst(); X Recur(); X SetWind(savewp); X SpelParse(Spell); X} X void SpelWords() X{ X char *buftospel; X Buffer *wordsb = curbuf; X X if ((buftospel = ask_buf((Buffer *) 0)) == 0) X return; X SetBuf(do_select(curwind, buftospel)); X SpelParse(wordsb->b_name); X} X void SpelParse(bname) char *bname; X{ X Buffer *buftospel, X *wordsb; X char wordspel[100]; X Bufpos *bp; X struct error *ep = 0; X X ErrFree(); /* This is important! */ X X buftospel = curbuf; X wordsb = buf_exists(bname); X perr_buf = wordsb; /* This is important (buffer containing X error messages) */ X SetBuf(wordsb); X ToFirst(); X f_mess("Finding misspelled words ... "); X while (!lastp(curline)) { X sprintf(wordspel, "\\<%s\\>", linebuf); X SetBuf(buftospel); X ToFirst(); X while (bp = dosearch(wordspel, 1, 1)) { X SetDot(bp); X ep = AddError(ep, wordsb->b_dot, buftospel, X curline, curchar); X } X SetBuf(wordsb); X line_move(FORWARD, 1, NO); X } X add_mess("Done."); X SetBuf(buftospel); X ShowErr(); X} X X#endif /* SPELL */ X void ShToBuf() X{ X char bufname[128], X cmd[128]; X X strcpy(bufname, ask((char *) 0, "Buffer: ")); X strcpy(cmd, ask(ShcomBuf, "Command: ")); X DoShell(bufname, cmd); X} X void ShellCom() X{ X null_ncpy(ShcomBuf, ask(ShcomBuf, ProcFmt), (sizeof ShcomBuf) - 1); X DoShell(MakeName(ShcomBuf), ShcomBuf); X} X ShNoBuf() X{ X int status; X X null_ncpy(ShcomBuf, ask(ShcomBuf, ProcFmt), (sizeof ShcomBuf) - 1); X status = UnixToBuf((char *) 0, NO, 0, NO, Shell, ShFlags, ShcomBuf, (char *) 0); X com_finish(status, ShcomBuf); X} X Shtypeout() X{ X int status; X X null_ncpy(ShcomBuf, ask(ShcomBuf, ProcFmt), (sizeof ShcomBuf) - 1); X status = UnixToBuf((char *) 0, YES, 0, NO, Shell, ShFlags, ShcomBuf, (char *) 0); X if (status == 0) X Typeout("[%s: completed successfully]", ShcomBuf); X else X Typeout("[%s: exited (%d)]", ShcomBuf, status); X TOstop(); X} X X/* Run the shell command into `bufname'. Empty the buffer except when we X give a numeric argument, in which case it inserts the output at the X current position in the buffer. */ X private void DoShell(bufname, command) char *bufname, X *command; X{ X Window *savewp = curwind; X int status; X X status = UnixToBuf(bufname, YES, 0, !is_an_arg(), Shell, X ShFlags, command, (char *) 0); X com_finish(status, command); X SetWind(savewp); X} X private void com_finish(status, cmd) int status; char *cmd; X{ X s_mess("[%s: ", cmd); X if (status == 0) X add_mess("completed successfully"); X else X add_mess("exited (%d)", status); X add_mess("]"); X} X X#ifndef MSDOS void dowait(pid, status) int pid, X *status; X{ X#ifndef IPROCS X X int rpid; X X while ((rpid = wait(status)) != pid) X ; X#else X X#ifdef BSD4_2 X# include <sys/wait.h> X#else X# include <wait.h> X#endif X X union wait w; X int rpid; X X for (;;) { X#ifndef BSD4_2 X rpid = wait2(&w.w_status, 0); X#else X rpid = wait3(&w, 0, (struct rusage *) 0); X#endif X if (rpid == pid) { X if (status) X *status = w.w_status; X break; X } else X kill_off(rpid, w); X } X#endif /* IPROCS */ X} X X#endif /* MSDOS */ X/* Run the command to bufname, erase the buffer if clobber is non-zero, X and redisplay if disp is non-zero. Leaves current buffer in `bufname' X and leaves any windows it creates lying around. It's up to the caller X to fix everything up after we're done. (Usually there's nothing to X fix up.) */ X X/* VARARGS5 */ X int UnixToBuf(bufname, disp, wsize, clobber, va_alist) char *bufname; va_dcl X{ X#ifndef MSDOS X int p[2], X pid, X status, X#else /* MSDOS */ X int p0, X oldo, X olde, X retcode, X#endif /* MSDOS */ X eof; X va_list ap; X char *argv[32], X *mess; X File *fp; X int (*old_int)(); X X va_start(ap); X make_argv(argv, ap); X va_end(ap); X if (bufname != 0 && clobber == YES) X isprocbuf(bufname); X if (disp) { X if (bufname != 0) X message("Starting up..."); X else { X TOstart(argv[0], TRUE); X Typeout("Starting up..."); X } X if (bufname != 0) { X pop_wind(bufname, clobber, clobber ? B_PROCESS : B_FILE); X set_wsize(wsize); X redisplay(); X } X } X /* Now I will attempt to describe how I deal with signals during X the execution of the shell command. My desire was to be able X to interrupt the shell command AS SOON AS the window pops up. X So, if we have JOB_CONTROL (i.e., the new signal mechanism) I X hold SIGINT, meaning if we interrupt now, we will eventually X see the interrupt, but not before we are ready for it. We X fork, the child releases the interrupt, it then sees the X interrupt, and so exits. Meanwhile the parent ignores the X signal, so if there was a pending one, it's now lost. X X With no JOB_CONTROL, the best behavior you can expect is, when X you type ^] too very quickly after the window pops up, it may X be ignored. The behavior BEFORE was that it would interrupt X JOVE and then you would have to continue JOVE and wait a X little while longer before trying again. Now that is fixed, X in that you just have to type it twice. */ X X#ifndef MSDOS X#ifdef IPROCS X sighold(SIGCHLD); X#endif X#ifdef JOB_CONTROL X sighold(SIGINT); X#else X old_int = signal(SIGINT, SIG_IGN), X#endif X dopipe(p); X pid = fork(); X if (pid == -1) { X pclose(p); X complain("[Fork failed]"); X } X if (pid == 0) { X#ifdef IPROCS X sigrelse(SIGCHLD); /* don't know if this matters */ X#endif /* IPROCS */ X (void) signal(SIGINT, SIG_DFL); X#ifdef JOB_CONTROL X sigrelse(SIGINT); X#endif X (void) close(0); X (void) open("/dev/null", 0); X (void) close(1); X (void) close(2); X (void) dup(p[1]); X (void) dup(p[1]); X pclose(p); X execv(argv[0], &argv[1]); X (void) write(1, "Execl failed.\n", 14); X _exit(1); X } X#ifdef JOB_CONTROL X old_int = signal(SIGINT, SIG_IGN); X#endif X (void) close(p[1]); X fp = fd_open(argv[1], F_READ, p[0], iobuff, LBSIZE); X#else /* MSDOS */ X if ((p0 = openforpipe()) < 0) X complain("cannot make pipe for filter"); X X oldo = dup(1); X olde = dup(2); X close(1); X close(2); X dup(p0); X dup(1); X close(p0); X retcode = spawnv(0, argv[0], &argv[1]); X p0 = reopenforpipe(); X close(1); X close(2); X dup(oldo); X dup(olde); X close(oldo); X close(olde); X X if (retcode < 0) X complain("[Spawn failed]"); X X fp = fd_open(argv[1], F_READ, p0, iobuff, LBSIZE); X#endif /* MSDOS */ X do { X#ifndef MSDOS X inIOread = 1; X#endif X eof = f_gets(fp, genbuf, LBSIZE); X#ifndef MSDOS X inIOread = 0; X#endif X if (bufname != 0) { X ins_str(genbuf, YES); X if (!eof) X LineInsert(1); X } else if (disp == YES) X Typeout("%s", genbuf); X if (bufname != 0 && disp != 0 && fp->f_cnt <= 0) { X#ifdef LOAD_AV X { X double theavg; X X get_la(&theavg); X if (theavg < 2.0) X mess = "Screaming along..."; X else if (theavg < 5.0) X mess = "Chugging along..."; X else X mess = "Crawling along..."; X } X#else X mess = "Chugging along..."; X#endif /* LOAD_AV */ X if (bufname != 0) { X message(mess); X redisplay(); X } X } X } while (!eof); X if (disp) X DrawMesg(NO); X close_file(fp); X#ifndef MSDOS X dowait(pid, &status); X#ifdef JOB_CONTROL X (void) sigrelse(SIGINT); X#endif X#else /* MSDOS */ X closepipe(); X#endif /* MSDOS */ X (void) signal(SIGINT, old_int); X#ifndef MSDOS X#ifdef IPROCS X sigrelse(SIGCHLD); X#endif X return status; X#else /* MSDOS */ X#ifdef CHDIR X getCWD(); X#endif X return retcode; X#endif /* MSDOS */ X} X X#ifndef MSDOS X#ifdef BSD4_2 X private long SigMask = 0; X X#ifndef sigmask X# define sigmask(s) (1L << ((s)-1)) X#endif X sighold(sig) X{ X (void) sigblock(SigMask |= sigmask(sig)); X} X sigrelse(sig) X{ X (void) sigsetmask(SigMask &= ~sigmask(sig)); X} X X#endif X X#endif /* MSDOS */ X void FilterRegion() X{ X char *cmd = ask((char *) 0, ": %f (through command) ", ProcFmt); X X RegToUnix(curbuf, cmd); X} X X/* Send the current region to CMD and insert the output from the X command into OUT_BUF. */ X void RegToUnix(outbuf, cmd) Buffer *outbuf; char *cmd; X{ X Mark *m = CurMark(); X#ifndef MSDOS X char *tname = mktemp("/tmp/jfilterXXXXXX"), X combuf[128]; X#endif /* MSDOS */ X Window *save_wind = curwind; X int status, X error = NO; X#ifdef MSDOS X int p0, oldi; X#endif /* MSDOS */ X File *fp; X X#ifndef MSDOS X fp = open_file(tname, iobuff, F_WRITE, COMPLAIN, QUIET); X#else /* MSDOS */ X p0 = openforpipe(); X#endif /* MSDOS */ X CATCH X#ifdef MSDOS X fp = fd_open(cmd, F_WRITE, p0, iobuff, LBSIZE); X#endif /* MSDOS */ X putreg(fp, m->m_line, m->m_char, curline, curchar, YES); X DelReg(); X#ifndef MSDOS X sprintf(combuf, "%s < %s", cmd, tname); X#else /* MSDOS */ X f_close(fp); X p0 = reopenforpipe(); X oldi = dup(0); X close(0); X dup(p0); X close(p0); X#endif /* MSDOS */ X status = UnixToBuf(outbuf->b_name, NO, 0, outbuf->b_type == B_SCRATCH, X#ifndef MSDOS X Shell, ShFlags, combuf, (char *) 0); X#else /* MSDOS */ X Shell, ShFlags, cmd, (char *) 0); X#endif /* MSDOS */ X ONERROR X error = YES; X ENDCATCH X#ifndef MSDOS X f_close(fp); X (void) unlink(tname); X#else /* MSDOS */ X close(0); X open("con", 0); /* dup(oldi); */ X close(oldi); X closepipe(); X#endif /* MSDOS */ X SetWind(save_wind); X if (error == NO) X#ifndef MSDOS X com_finish(status, combuf); X#else X com_finish(status, cmd); X#endif X} X void isprocbuf(bufname) char *bufname; X{ X Buffer *bp; X X if ((bp = buf_exists(bufname)) != 0 && bp->b_type != B_PROCESS) X confirm("Over-write buffer %s?", bufname); X} X X#ifdef MSDOS X/* msdos specific hacks to allow for pipes */ X X#include <dos.h> X#include <fcntl.h> X#include <sys/types.h> X#include <sys/stat.h> X static char pipeiname[64]; static char pipeoname[64]; static int pipehandle; X extern char TmpFilePath[]; X private int openforpipe() X{ X sprintf(pipeiname, "%s/%s", TmpFilePath, "Jove-I"); X sprintf(pipeoname, "%s/%s", TmpFilePath, "Jove-O"); X X return(pipehandle = creat(pipeoname, S_IWRITE|S_IREAD)); X} X private int reopenforpipe() X{ X close(pipehandle); X unlink(pipeiname); X rename(pipeoname, pipeiname); X if ((pipehandle = open(pipeiname, 0)) >= 0) X return(pipehandle); X closepipe(); X return(-1); X} X private void closepipe() X{ X unlink(pipeoname); X unlink(pipeiname); X} X char switchar() X{ X union REGS regs; X X regs.h.ah = 0x37; X regs.h.al = 0; X intdos(®s, ®s); X return(regs.h.dl); X} X#endif /* MSDOS */ END_OF_FILE if test 18101 -ne `wc -c <'./proc.c'`; then echo shar: \"'./proc.c'\" unpacked with wrong size! fi # end of './proc.c' fi echo shar: End of archive 9 \(of 21\). cp /dev/null ark9isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 21 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.