+++ /dev/null
-
-/*
- * vmh.c -- visual front-end to nmh
- *
- * This code is Copyright (c) 2002, by the authors of nmh. See the
- * COPYRIGHT file in the root directory of the nmh distribution for
- * complete copyright information.
- */
-
-#include <h/mh.h>
-#include <h/signals.h>
-
-#if 0
-#if defined(SYS5) && !defined(TERMINFO)
-/*
- * Define TERMINFO if you have it.
- * You get it automatically if you're running SYS5, and you don't get
- * it if you're not. (If you're not SYS5, you probably have termcap.)
- * We distinguish TERMINFO from SYS5 because in this file SYS5 really
- * means "AT&T line discipline" (termio, not sgttyb), whereas terminfo
- * is quite a separate issue.
- */
-#define TERMINFO 1
-#endif
-#endif
-
-/*
- * TODO:
- * 1) Pass signals to client during execution
- * 2) Figure out a way for the user to say how big the Scan/Display
- * windows should be.
- * 3) If curses ever gets fixed, then XYZ code can be removed
- */
-
-#include <curses.h>
-
-#ifdef ncr
-# define _SYS_REG_H /* NCR redefines "ERR" in <sys/reg.h> */
-#endif
-
-#undef OK /* tricky */
-
-/* removed for right now */
-#if 0
-#ifdef TERMINFO
-# include <term.h> /* variables describing terminal capabilities */
-#endif /* TERMINFO */
-#endif
-
-#include <h/vmhsbr.h>
-#include <errno.h>
-#include <setjmp.h>
-#include <signal.h>
-
-#ifndef sigmask
-# define sigmask(s) (1 << ((s) - 1))
-#endif /* not sigmask */
-
-#ifdef ridge
-# undef SIGTSTP
-#endif /* ridge */
-
-#ifdef HAVE_WRITEV
-# include <sys/uio.h>
-#else
-struct iovec {
- char *iov_base;
- int iov_len;
-};
-#endif
-
-#ifdef hpux
-# include <termio.h>
-# define TCGETATTR /* tcgetattr() */
-#endif
-
-#ifdef BSD44
-# define USE_OLD_TTY
-# define _maxx maxx /* curses.h */
-# define _maxy maxy
-# define _curx curx /* curses.h */
-# define _cury cury
-void __cputchar __P((int));
-# undef _putchar
-# define _putchar __cputchar
-# include <sys/ioctl.h> /* sgttyb */
-#endif
-
-#define ALARM ((unsigned int) 10)
-#define PAUSE ((unsigned int) 2)
-
-#ifndef abs
-# define abs(a) ((a) > 0 ? (a) : -(a))
-#endif
-
-#define SMALLMOVE 1
-#define LARGEMOVE 10
-
-#define XYZ /* XXX */
-
-static struct swit switches[] = {
-#define PRMPTSW 0
- { "prompt string", 6 },
-#define PROGSW 1
- { "vmhproc program", 7 },
-#define NPROGSW 2
- { "novmhproc", 9 },
-#define VERSIONSW 3
- { "version", 0 },
-#define HELPSW 4
- { "help", 0 },
- { NULL, 0 }
-};
-
- /* PEERS */
-static int PEERpid = NOTOK;
-
-static jmp_buf PEERctx;
-
- /* WINDOWS */
-static char *myprompt = "(%s) ";
-
-static WINDOW *Scan;
-static WINDOW *Status;
-static WINDOW *Display;
-static WINDOW *Command;
-
-#define NWIN 3
-static int numwins;
-WINDOW *windows[NWIN + 1];
-
-
- /* LINES */
-
-struct line {
- int l_no;
- char *l_buf;
- struct line *l_prev;
- struct line *l_next;
-};
-
-static struct line *lhead = NULL;
-static struct line *ltop = NULL;
-static struct line *ltail = NULL;
-
-static int did_less = 0;
-static int smallmove = SMALLMOVE;
-static int largemove = LARGEMOVE;
-
-
- /* TTYS */
-
-static int tty_ready = NOTOK;
-
-static int intrc;
-
-#ifndef SYS5
-# define ERASE sg.sg_erase
-# define KILL sg.sg_kill
-static struct sgttyb sg;
-
-#define EOFC tc.t_eofc
-#define INTR tc.t_intrc
-static struct tchars tc;
-#else /* SYS5 */
-# define ERASE sg.c_cc[VERASE]
-# define KILL sg.c_cc[VKILL]
-# define EOFC sg.c_cc[VEOF]
-# define INTR sg.c_cc[VINTR]
-static struct termio sg;
-#endif /* SYS5 */
-
-#ifndef TIOCGLTC
-# define WERASC ('W' & 037)
-#else /* TIOCGLTC */
-# ifndef SVR4
-# define WERASC ltc.t_werasc
-static struct ltchars ltc;
-# else /* SVR4 */
-# define WERASC sg.c_cc[VWERASE]
-# undef TIOCGLTC /* the define exists, but struct ltchars doesn't */
-# endif
-#endif /* TIOCGLTC */
-
-
-#if !defined(SYS5) && !defined(BSD44)
-int _putchar();
-#endif /* not SYS5 */
-
-#ifdef SIGTSTP
-char *tgoto();
-#endif /* SIGTSTP */
-
- /* SIGNALS */
-static RETSIGTYPE ALRMser(int);
-static RETSIGTYPE PIPEser(int);
-static RETSIGTYPE SIGser(int);
-#ifdef SIGTSTP
-static RETSIGTYPE TSTPser(int);
-#endif /* SIGTSTP */
-
-
- /* MISCELLANY */
-
-/*
- * static prototypes
- */
-static void adorn (char *, char *, ...);
-
-static vmh(), lreset(), linsert(), ladvance(), lretreat(), lgo();
-static TTYon(), TTYoff(), foreground();
-static int PEERinit(), pINI(), pLOOP(), pTTY(), pWIN(), WINinit();
-static int WINgetstr(), WINless(), WINputc(), TTYinit(), pWINaux();
-
-
-int
-main (int argc, char **argv)
-{
- int vecp = 1, nprog = 0;
- char *cp, buffer[BUFSIZ];
- char **argp, **arguments, *vec[MAXARGS];
-
-#ifdef LOCALE
- setlocale(LC_ALL, "");
-#endif
- invo_name = r1bindex (argv[0], '/');
-
- /* read user profile/context */
- context_read();
-
- arguments = getarguments (invo_name, argc, argv, 1);
- argp = arguments;
-
- while ((cp = *argp++))
- if (*cp == '-')
- switch (smatch (++cp, switches)) {
- case AMBIGSW:
- ambigsw (cp, switches);
- done (1);
- case UNKWNSW:
- vec[vecp++] = --cp;
- continue;
-
- case HELPSW:
- snprintf (buffer, sizeof(buffer), "%s [switches for vmhproc]",
- invo_name);
- print_help (buffer, switches, 1);
- done (1);
- case VERSIONSW:
- print_version(invo_name);
- done (1);
-
- case PRMPTSW:
- if (!(myprompt = *argp++) || *myprompt == '-')
- adios (NULL, "missing argument to %s", argp[-2]);
- continue;
-
- case PROGSW:
- if (!(vmhproc = *argp++) || *vmhproc == '-')
- adios (NULL, "missing argument to %s", argp[-2]);
- continue;
- case NPROGSW:
- nprog++;
- continue;
- }
- else
- vec[vecp++] = cp;
-
- if (TTYinit (nprog) == NOTOK || WINinit (nprog) == NOTOK) {
- vec[vecp] = NULL;
-
- vec[0] = r1bindex (vmhproc, '/');
- execvp (vmhproc, vec);
- adios (vmhproc, "unable to exec");
- }
- TTYoff ();
- PEERinit (vecp, vec);
- TTYon ();
-
- vmh ();
-
- return done (0);
-}
-
-
-static void
-vmh (void)
-{
- char buffer[BUFSIZ];
-
- for (;;) {
- pLOOP (RC_QRY, NULL);
-
- wmove (Command, 0, 0);
- wprintw (Command, myprompt, invo_name);
- wclrtoeol (Command);
- wrefresh (Command);
-
- switch (WINgetstr (Command, buffer)) {
- case NOTOK:
- break;
-
- case OK:
- done (0); /* NOTREACHED */
-
- default:
- if (*buffer)
- pLOOP (RC_CMD, buffer);
- break;
- }
- }
-}
-
-/* PEERS */
-
-static int
-PEERinit (int vecp, char *vec[])
-{
- int pfd0[2], pfd1[2];
- char buf1[BUFSIZ], buf2[BUFSIZ];
-
- if (pipe (pfd0) == NOTOK || pipe (pfd1) == NOTOK)
- adios ("pipe", "unable to");
-#ifdef hpux
- switch (PEERpid = fork ()) {
- /*
- * Calling vfork() and then another routine [like close()] before
- * an exec() messes up the stack frame, causing crib death.
- * Use fork() instead.
- */
-#else /* not hpux */
- switch (PEERpid = vfork ()) {
-#endif /* not hpux */
- case NOTOK:
- adios ("vfork", "unable to");/* NOTREACHED */
-
- case OK:
- close (pfd0[0]);
- close (pfd1[1]);
-
- vec[vecp++] = "-vmhread";
- snprintf (buf1, sizeof(buf1), "%d", pfd1[0]);
- vec[vecp++] = buf1;
- vec[vecp++] = "-vmhwrite";
- snprintf (buf2, sizeof(buf2), "%d", pfd0[1]);
- vec[vecp++] = buf2;
- vec[vecp] = NULL;
-
- SIGNAL (SIGINT, SIG_DFL);
- SIGNAL (SIGQUIT, SIG_DFL);
-
- vec[0] = r1bindex (vmhproc, '/');
- execvp (vmhproc, vec);
- perror (vmhproc);
- _exit (-1); /* NOTREACHED */
-
- default:
- close (pfd0[1]);
- close (pfd1[0]);
-
- rcinit (pfd0[0], pfd1[1]);
- return pINI ();
- }
-}
-
-
-static int
-pINI (void)
-{
- int len, buflen;
- char *bp, buffer[BUFSIZ];
- struct record rcs;
- register struct record *rc = &rcs;
- register WINDOW **w;
-
- initrc (rc);
-
- /* Get buffer ready to go */
- bp = buffer;
- buflen = sizeof(buffer);
-
- snprintf (bp, buflen, "%d %d", RC_VRSN, numwins);
- len = strlen (bp);
- bp += len;
- buflen -= len;
-
- for (w = windows; *w; w++) {
- snprintf (bp, buflen, " %d", (*w)->_maxy);
- len = strlen (bp);
- bp += len;
- buflen -= len;
- }
-
- switch (str2rc (RC_INI, buffer, rc)) {
- case RC_ACK:
- return OK;
-
- case RC_ERR:
- if (rc->rc_len)
- adios (NULL, "%s", rc->rc_data);
- else
- adios (NULL, "pINI peer error");
-
- case RC_XXX:
- adios (NULL, "%s", rc->rc_data);
-
- default:
- adios (NULL, "pINI protocol screw-up");
- }
-/* NOTREACHED */
-}
-
-
-static int
-pLOOP (char *code, char *str)
-{
- int i;
- struct record rcs;
- register struct record *rc = &rcs;
-
- initrc (rc);
-
- str2peer (code, str);
- for (;;)
- switch (peer2rc (rc)) {
- case RC_TTY:
- if (pTTY (rc) == NOTOK)
- return NOTOK;
- break;
-
- case RC_WIN:
- if (sscanf (rc->rc_data, "%d", &i) != 1
- || i <= 0
- || i > numwins) {
- fmt2peer (RC_ERR, "no such window \"%s\"", rc->rc_data);
- return NOTOK;
- }
- if (pWIN (windows[i - 1]) == NOTOK)
- return NOTOK;
- break;
-
- case RC_EOF:
- return OK;
-
- case RC_ERR:
- if (rc->rc_len)
- adorn (NULL, "%s", rc->rc_data);
- else
- adorn (NULL, "pLOOP(%s) peer error",
- code == RC_QRY ? "QRY" : "CMD");
- return NOTOK;
-
- case RC_FIN:
- if (rc->rc_len)
- adorn (NULL, "%s", rc->rc_data);
- rcdone ();
- i = pidwait (PEERpid, OK);
- PEERpid = NOTOK;
- done (i);
-
- case RC_XXX:
- adios (NULL, "%s", rc->rc_data);
-
- default:
- adios (NULL, "pLOOP(%s) protocol screw-up",
- code == RC_QRY ? "QRY" : "CMD");
- }
-}
-
-
-static int
-pTTY (struct record *r)
-{
- SIGNAL_HANDLER hstat, istat, qstat, tstat;
- struct record rcs;
- register struct record *rc = &rcs;
-
- initrc (rc);
-
- TTYoff ();
-
- /* should be changed to block instead of ignore */
- hstat = SIGNAL (SIGHUP, SIG_IGN);
- istat = SIGNAL (SIGINT, SIG_IGN);
- qstat = SIGNAL (SIGQUIT, SIG_IGN);
- tstat = SIGNAL (SIGTERM, SIG_IGN);
-
- rc2rc (RC_ACK, 0, NULL, rc);
-
- SIGNAL (SIGHUP, hstat);
- SIGNAL (SIGINT, istat);
- SIGNAL (SIGQUIT, qstat);
- SIGNAL (SIGTERM, tstat);
-
- TTYon ();
-
- if (r->rc_len && strcmp (r->rc_data, "FAST") == 0)
- goto no_refresh;
-
-#ifdef SIGTSTP
- SIGNAL (SIGTSTP, SIG_IGN);
-#endif
-
-#ifndef TERMINFO
- if (SO)
- tputs (SO, 0, _putchar);
-#else /* TERMINFO */
- putp(enter_standout_mode);
-#endif /* TERMINFO */
- fprintf (stdout, "Type any key to continue... ");
- fflush (stdout);
-#ifndef TERMINFO
- if (SE)
- tputs (SE, 0, _putchar);
-#else /* TERMINFO */
- putp(exit_standout_mode);
-#endif /* TERMINFO */
- getc (stdin);
-#ifdef SIGTSTP
- SIGNAL (SIGTSTP, TSTPser);
-#endif /* SIGTSTP */
-
- wrefresh (curscr);
-
-no_refresh: ;
- switch (rc->rc_type) {
- case RC_EOF:
- rc2peer (RC_ACK, 0, NULL);
- return OK;
-
- case RC_ERR:
- if (rc->rc_len)
- adorn (NULL, "%s", rc->rc_data);
- else
- adorn (NULL, "pTTY peer error");
- return NOTOK;
-
- case RC_XXX:
- adios (NULL, "%s", rc->rc_data);
-
- default:
- adios (NULL, "pTTY protocol screw-up");
- }
-/* NOTREACHED */
-}
-
-
-static int
-pWIN (WINDOW *w)
-{
- int i;
-
- did_less = 0;
- if ((i = pWINaux (w)) == OK && did_less)
- WINless (w, 1);
-
- lreset ();
-
- return i;
-}
-
-
-static int
-pWINaux (WINDOW *w)
-{
- register int n;
- int eol;
- register char c, *bp;
- struct record rcs;
- register struct record *rc = &rcs;
-
- initrc (rc);
-
- werase (w);
- wmove (w, 0, 0);
-#ifdef XYZ
- if (w == Status)
- wstandout (w);
-#endif /* XYZ */
-
- for (eol = 0;;)
- switch (rc2rc (RC_ACK, 0, NULL, rc)) {
- case RC_DATA:
- if (eol && WINputc (w, '\n') == ERR && WINless (w, 0))
- goto flush;
- for (bp = rc->rc_data, n = rc->rc_len; n-- > 0; ) {
- if ((c = *bp++) == '\n')
- linsert (w);
- if (WINputc (w, c) == ERR)
- if (n == 0 && c == '\n')
- eol++;
- else
- if (WINless (w, 0)) {
-flush: ;
- fmt2peer (RC_ERR, "flush window");
-#ifdef XYZ /* should NEVER happen... */
- if (w == Status)
- wstandend (w);
-#endif /* XYZ */
- wrefresh (w);
- return NOTOK;
- }
- }
- break;
-
- case RC_EOF:
- rc2peer (RC_ACK, 0, NULL);
-#ifdef XYZ
- if (w == Status)
- wstandend (w);
-#endif /* XYZ */
- wrefresh (w);
- return OK;
-
- case RC_ERR:
- if (rc->rc_len)
- adorn (NULL, "%s", rc->rc_data);
- else
- adorn (NULL, "pWIN peer error");
- return NOTOK;
-
- case RC_XXX:
- adios (NULL, "%s", rc->rc_data);
-
- default:
- adios (NULL, "pWIN protocol screw-up");
- }
-/* NOTREACHED */
-}
-
-
-static int
-pFIN (void)
-{
- int status;
-
- if (PEERpid <= OK)
- return OK;
-
- rc2peer (RC_FIN, 0, NULL);
- rcdone ();
-
- switch (setjmp (PEERctx)) {
- case OK:
- SIGNAL (SIGALRM, ALRMser);
- alarm (ALARM);
-
- status = pidwait (PEERpid, OK);
-
- alarm (0);
- break;
-
- default:
- kill (PEERpid, SIGKILL);
- status = NOTOK;
- break;
- }
- PEERpid = NOTOK;
-
- return status;
-}
-
-/* WINDOWS */
-
-static int
-WINinit (int nprog)
-{
- register int nlines, /* not "lines" because terminfo uses that */
- top,
- bottom;
-
- foreground ();
- if (initscr () == (WINDOW *) ERR)
- if (nprog)
- return NOTOK;
- else
- adios (NULL, "could not initialize terminal");
-#ifdef SIGTSTP
- SIGNAL (SIGTSTP, SIG_DFL);
-#endif /* SIGTSTP */
- sideground ();
-
-#ifndef TERMINFO
- if (CM == NULL)
-#else /* TERMINFO */
- if (cursor_address == NULL) /* assume mtr wanted "cm", not "CM" */
-#endif /* TERMINFO */
- if (nprog)
- return NOTOK;
- else
- adios (NULL,
- "sorry, your terminal isn't powerful enough to run %s",
- invo_name);
-
-#ifndef TERMINFO
- if (tgetflag ("xt") || tgetnum ("sg") > 0)
- SO = SE = US = UE = NULL;
-#else /* TERMINFO */
-/*
- * If termcap mapped directly to terminfo, we'd use the following:
- * if (teleray_glitch || magic_cookie_glitch > 0)
- * enter_standout_mode = exit_standout_mode =
- * enter_underline_mode = exit_underline_mode = NULL;
- * But terminfo does the right thing so we don't have to resort to that.
- */
-#endif /* TERMINFO */
-
- if ((nlines = LINES - 1) < 11)
- adios (NULL, "screen too small");
- if ((top = nlines / 3 + 1) > LINES / 4 + 2)
- top--;
- bottom = nlines - top - 2;
-
- numwins = 0;
- Scan = windows[numwins++] = newwin (top, COLS, 0, 0);
- Status = windows[numwins++] = newwin (1, COLS, top, 0);
-#ifndef XYZ
- wstandout (Status);
-#endif /* XYZ */
- Display = windows[numwins++] = newwin (bottom, COLS, top + 1, 0);
- Command = newwin (1, COLS - 1, top + 1 + bottom, 0);
- windows[numwins] = NULL;
-
- largemove = Display->_maxy / 2 + 2;
- return OK;
-}
-
-
-static int WINgetstr (WINDOW *w, char *buffer)
-{
- register int c;
- register char *bp;
-
- bp = buffer;
- *bp = 0;
-
- for (;;) {
- switch (c = toascii (wgetch (w))) {
- case ERR:
- adios (NULL, "wgetch lost");
-
- case '\f':
- wrefresh (curscr);
- break;
-
- case '\r':
- case '\n':
- *bp = 0;
- if (bp > buffer) {
- leaveok (curscr, FALSE);
- wmove (w, 0, w->_curx - (bp - buffer));
- wrefresh (w);
- leaveok (curscr, TRUE);
- }
- return DONE;
-
- default:
- if (c == intrc) {
- wprintw (w, " ");
- wstandout (w);
- wprintw (w, "Interrupt");
- wstandend (w);
- wrefresh (w);
- *buffer = 0;
- return NOTOK;
- }
- if (c == EOFC) {
- if (bp <= buffer)
- return OK;
- break;
- }
- if (c == ERASE) {
- if (bp <= buffer)
- continue;
- bp--, w->_curx--;
- wclrtoeol (w);
- break;
- }
- if (c == KILL) {
- if (bp <= buffer)
- continue;
- w->_curx -= bp - buffer;
- bp = buffer;
- wclrtoeol (w);
- break;
- }
- if (c == WERASC) {
- if (bp <= buffer)
- continue;
- do {
- bp--, w->_curx--;
- } while (isspace (*bp) && bp > buffer);
-
- if (bp > buffer) {
- do {
- bp--, w->_curx--;
- } while (!isspace (*bp) && bp > buffer);
- if (isspace (*bp))
- bp++, w->_curx++;
- }
- wclrtoeol (w);
- break;
- }
-
- if (c >= ' ' && c < '\177')
- waddch (w, *bp++ = c);
- break;
- }
-
- wrefresh (w);
- }
-}
-
-
-static int
-WINwritev (WINDOW *w, struct iovec *iov, int n)
-{
- register int i;
-
- werase (w);
- wmove (w, 0, 0);
- for (i = 0; i < n; i++, iov++)
- wprintw (w, "%*.*s", iov->iov_len, iov->iov_len, iov->iov_base);
- wrefresh (w);
-
- sleep (PAUSE);
-
- return OK;
-}
-
-
-static struct {
- char *h_msg;
- int *h_val;
-} hlpmsg[] = {
- " forward backwards", NULL,
- " ------- ---------", NULL,
- "next screen SPACE", NULL,
- "next %d line%s RETURN y", &smallmove,
- "next %d line%s EOT u", &largemove,
- "go g G", NULL,
- "", NULL,
- "refresh CTRL-L", NULL,
- "quit q", NULL,
-
- NULL, NULL
-};
-
-
-static int
-WINless (WINDOW *w, int fin)
-{
- register int c, i, n;
- char *cp;
- register struct line *lbottom;
- int nfresh, nwait;
-
-#ifdef notdef
- int nlatch;
-#endif
-
- did_less++;
-
- cp = NULL;
-#ifdef notdef
- if (fin)
- ltop = NULL;
-#endif /* notdef */
- lbottom = NULL;
- nfresh = 1;
- nwait = 0;
- wrefresh (w);
-
- for (;;) {
- if (nfresh || nwait) {
- nfresh = 0;
-#ifdef notdef
- nlatch = 1;
-
-once_only: ;
-#endif /* notdef */
- werase (w);
- wmove (w, 0, 0);
-
- if (ltop == NULL)
- if (fin) {
- lgo (ltail->l_no - w->_maxy + 1);
- if (ltop == NULL)
- ltop = lhead;
- }
- else
- ltop = lbottom && lbottom->l_prev ? lbottom->l_prev
- : lbottom;
-
- for (lbottom = ltop; lbottom; lbottom = lbottom->l_next)
- if (waddstr (w, lbottom->l_buf) == ERR
- || waddch (w, '\n') == ERR)
- break;
- if (lbottom == NULL)
- if (fin) {
-#ifdef notdef
- if (nlatch && (ltail->l_no >= w->_maxy)) {
- lgo (ltail->l_no - w->_maxy + 1);
- nlatch = 0;
- goto once_only;
- }
-#endif /* notdef */
- lbottom = ltail;
- while (waddstr (w, "~\n") != ERR)
- continue;
- }
- else {
- wrefresh (w);
- return 0;
- }
-
- if (!nwait)
- wrefresh (w);
- }
-
- wmove (Command, 0, 0);
- if (cp) {
- wstandout (Command);
- wprintw (Command, "%s", cp);
- wstandend (Command);
- cp = NULL;
- }
- else
- wprintw (Command, fin ? "top:%d bot:%d end:%d" : "top:%d bot:%d",
- ltop->l_no, lbottom->l_no, ltail->l_no);
- wprintw (Command, ">> ");
- wclrtoeol (Command);
- wrefresh (Command);
-
- c = toascii (wgetch (Command));
-
- werase (Command);
- wrefresh (Command);
-
- if (nwait) {
- nwait = 0;
- wrefresh (w);
- }
-
- n = 0;
-again: ;
- switch (c) {
- case ' ':
- ltop = lbottom->l_next;
- nfresh++;
- break;
-
- case '\r':
- case '\n':
- case 'e':
- case 'j':
- if (n)
- smallmove = n;
- if (ladvance (smallmove))
- nfresh++;
- break;
-
- case 'y':
- case 'k':
- if (n)
- smallmove = n;
- if (lretreat (smallmove))
- nfresh++;
- break;
-
- case 'd':
- eof: ;
- if (n)
- largemove = n;
- if (ladvance (largemove))
- nfresh++;
- break;
-
- case 'u':
- if (n)
- largemove = n;
- if (lretreat (largemove))
- nfresh++;
- break;
-
- case 'g':
- if (lgo (n ? n : 1))
- nfresh++;
- break;
-
- case 'G':
- if (lgo (n ? n : ltail->l_no - w->_maxy + 1))
- nfresh++;
- break;
-
- case '\f':
- case 'r':
- wrefresh (curscr);
- break;
-
- case 'h':
- case '?':
- werase (w);
- wmove (w, 0, 0);
- for (i = 0; hlpmsg[i].h_msg; i++) {
- if (hlpmsg[i].h_val)
- wprintw (w, hlpmsg[i].h_msg, *hlpmsg[i].h_val,
- *hlpmsg[i].h_val != 1 ? "s" : "");
- else
- waddstr (w, hlpmsg[i].h_msg);
- waddch (w, '\n');
- }
- wrefresh (w);
- nwait++;
- break;
-
- case 'q':
- return 1;
-
- default:
- if (c == EOFC)
- goto eof;
-
- if (isdigit (c)) {
- wmove (Command, 0, 0);
- i = 0;
- while (isdigit (c)) {
- wprintw (Command, "%c", c);
- wrefresh (Command);
- i = i * 10 + c - '0';
- c = toascii (wgetch (Command));
- }
- werase (Command);
- wrefresh (Command);
-
- if (i > 0) {
- n = i;
- goto again;
- }
- cp = "bad number";
- }
- else
- cp = "not understood";
- break;
- }
- }
-}
-
-
-static int
-WINputc (WINDOW *w, char c)
-{
- register int x, y;
-
- switch (c) {
- default:
- if (!isascii (c)) {
- if (WINputc (w, 'M') == ERR || WINputc (w, '-') == ERR)
- return ERR;
- c = toascii (c);
- }
- else
- if (c < ' ' || c == '\177') {
- if (WINputc (w, '^') == ERR)
- return ERR;
- c ^= 0100;
- }
- break;
-
- case '\t':
- case '\n':
- break;
- }
-
- if (w != Scan)
- return waddch (w, c);
-
- if ((x = w->_curx) < 0 || x >= w->_maxx
- || (y = w->_cury) < 0 || y >= w->_maxy)
- return DONE;
-
- switch (c) {
- case '\t':
- for (x = 8 - (x & 0x07); x > 0; x--)
- if (WINputc (w, ' ') == ERR)
- return ERR;
- break;
-
- case '\n':
- if (++y < w->_maxy)
- waddch (w, c);
- else
- wclrtoeol (w);
- break;
-
- default:
- if (++x < w->_maxx)
- waddch (w, c);
- break;
- }
-
- return DONE;
-}
-
-/* LINES */
-
-static void
-lreset (void)
-{
- register struct line *lp, *mp;
-
- for (lp = lhead; lp; lp = mp) {
- mp = lp->l_next;
- free (lp->l_buf);
- free ((char *) lp);
- }
- lhead = ltop = ltail = NULL;
-}
-
-
-static void
-linsert (WINDOW *w)
-{
- register char *cp;
- register struct line *lp;
-
- if ((lp = (struct line *) calloc ((size_t) 1, sizeof *lp)) == NULL)
- adios (NULL, "unable to allocate line storage");
-
- lp->l_no = (ltail ? ltail->l_no : 0) + 1;
-#ifndef BSD44
- lp->l_buf = getcpy (w->_y[w->_cury]);
-#else
- lp->l_buf = getcpy (w->lines[w->_cury]->line);
-#endif
- for (cp = lp->l_buf + strlen (lp->l_buf) - 1; cp >= lp->l_buf; cp--)
- if (isspace (*cp))
- *cp = 0;
- else
- break;
-
- if (lhead == NULL)
- lhead = lp;
- if (ltop == NULL)
- ltop = lp;
- if (ltail)
- ltail->l_next = lp;
- lp->l_prev = ltail;
- ltail = lp;
-}
-
-
-static int
-ladvance (int n)
-{
- register int i;
- register struct line *lp;
-
- for (i = 0, lp = ltop; i < n && lp; i++, lp = lp->l_next)
- continue;
-
- if (ltop == lp)
- return 0;
-
- ltop = lp;
- return 1;
-}
-
-
-static int
-lretreat (int n)
-{
- register int i;
- register struct line *lp;
-
- for (i = 0, lp = ltop; i < n && lp; i++, lp = lp->l_prev)
- if (!lp->l_prev)
- break;
-
- if (ltop == lp)
- return 0;
-
- ltop = lp;
- return 1;
-}
-
-
-static int
-lgo (int n)
-{
- register int i, j;
- register struct line *lp;
-
- if ((i = n - (lp = lhead)->l_no)
- > (j = abs (n - (ltop ? ltop : ltail)->l_no)))
- i = j, lp = ltop ? ltop : ltail;
- if (i > (j = abs (ltail->l_no - n)))
- i = j, lp = ltail;
-
- if (n >= lp->l_no) {
- for (; lp; lp = lp->l_next)
- if (lp->l_no == n)
- break;
- }
- else {
- for (; lp; lp = lp->l_prev)
- if (lp->l_no == n)
- break;
- if (!lp)
- lp = lhead;
- }
-
- if (ltop == lp)
- return 0;
-
- ltop = lp;
- return 1;
-}
-
-/* TTYS */
-
-static int
-TTYinit (int nprog)
-{
- if (!isatty (fileno (stdin)) || !isatty (fileno (stdout)))
- if (nprog)
- return NOTOK;
- else
- adios (NULL, "not a tty");
-
- foreground ();
-#ifndef SYS5
- if (ioctl (fileno (stdin), TIOCGETP, (char *) &sg) == NOTOK)
- adios ("failed", "ioctl TIOCGETP");
- if (ioctl (fileno (stdin), TIOCGETC, (char *) &tc) == NOTOK)
- adios ("failed", "ioctl TIOCGETC");
-#else
-#ifdef TCGETATTR
- if( tcgetattr( fileno(stdin), &sg) == NOTOK)
- adios( "failed", "tcgetattr");
-#else /* SYS5 */
- if (ioctl (fileno (stdin), TCGETA, &sg) == NOTOK)
- adios ("failed", "ioctl TCGETA");
-#endif
-#endif
-#ifdef TIOCGLTC
- if (ioctl (fileno (stdin), TIOCGLTC, (char *) <c) == NOTOK)
- adios ("failed", "ioctl TIOCGLTC");
-#endif /* TIOCGLTC */
- intrc = INTR;
- sideground ();
-
- tty_ready = OK;
-
- SIGNAL (SIGPIPE, PIPEser);
-
- return OK;
-}
-
-
-static void
-TTYon (void)
-{
- if (tty_ready == DONE)
- return;
-
- INTR = NOTOK;
-#ifndef SYS5
- ioctl (fileno (stdin), TIOCSETC, (char *) &tc);
-#else /* SYS5 */
- ioctl (fileno (stdin), TCSETA, &sg);
-#endif /* SYS5 */
-
- crmode ();
- noecho ();
- nonl ();
- scrollok (curscr, FALSE);
-
- discard (stdin);
-
- tty_ready = DONE;
-
- SIGNAL (SIGHUP, SIGser);
- SIGNAL (SIGINT, SIGser);
- SIGNAL (SIGQUIT, SIGser);
-#ifdef SIGTSTP
- SIGNAL (SIGTSTP, TSTPser);
-#endif /* SIGTSTP */
-}
-
-
-static void
-TTYoff (void)
-{
- if (tty_ready == NOTOK)
- return;
-
- INTR = intrc;
-#ifndef SYS5
- ioctl (fileno (stdin), TIOCSETC, (char *) &tc);
-#else /* SYS5 */
- ioctl (fileno (stdin), TCSETA, &sg);
-#endif /* SYS5 */
-
- leaveok (curscr, TRUE);
- mvcur (0, COLS - 1, LINES - 1, 0);
- endwin ();
- if (tty_ready == DONE) {
-#ifndef TERMINFO
- if (CE)
- tputs (CE, 0, _putchar);
- else
-#else /* TERMINFO */
- putp(clr_eol);
-#endif /* TERMINFO */
- fprintf (stdout, "\r\n");
- }
- fflush (stdout);
-
- tty_ready = NOTOK;
-
- SIGNAL (SIGHUP, SIG_DFL);
- SIGNAL (SIGINT, SIG_DFL);
- SIGNAL (SIGQUIT, SIG_DFL);
-#ifdef SIGTSTP
- SIGNAL (SIGTSTP, SIG_DFL);
-#endif /* SIGTSTP */
-}
-
-
-static void
-foreground (void)
-{
-#ifdef TIOCGPGRP
- int pgrp, tpgrp;
- SIGNAL_HANDLER tstat;
-
- if ((pgrp = getpgrp()) == NOTOK)
- adios ("process group", "unable to determine");
- for (;;) {
- if (ioctl (fileno (stdin), TIOCGPGRP, (char *) &tpgrp) == NOTOK)
- adios ("tty's process group", "unable to determine");
- if (pgrp == tpgrp)
- break;
-
- tstat = SIGNAL (SIGTTIN, SIG_DFL);
- kill (0, SIGTTIN);
- SIGNAL (SIGTTIN, tstat);
- }
-
- SIGNAL (SIGTTIN, SIG_IGN);
- SIGNAL (SIGTTOU, SIG_IGN);
- SIGNAL (SIGTSTP, SIG_IGN);
-#endif /* TIOCGPGRP */
-}
-
-
-void
-sideground (void)
-{
-#ifdef TIOCGPGRP
- SIGNAL (SIGTTIN, SIG_DFL);
- SIGNAL (SIGTTOU, SIG_DFL);
- SIGNAL (SIGTSTP, SIG_DFL);
-#endif /* TIOCGPGRP */
-}
-
-/* SIGNALS */
-
-
-static RETSIGTYPE
-ALRMser (int sig)
-{
- longjmp (PEERctx, DONE);
-}
-
-
-#ifdef BSD42
-/* ARGSUSED */
-#endif /* BSD42 */
-
-static RETSIGTYPE
-PIPEser (int sig)
-{
-#ifndef RELIABLE_SIGNALS
- SIGNAL (sig, SIG_IGN);
-#endif
-
- adios (NULL, "lost peer");
-}
-
-
-static RETSIGTYPE
-SIGser (int sig)
-{
-#ifndef RELIABLE_SIGNALS
- SIGNAL (sig, SIG_IGN);
-#endif
-
- done (1);
-}
-
-
-#ifdef SIGTSTP
-static RETSIGTYPE
-TSTPser (int sig)
-{
-#ifndef TERMINFO
- tputs (tgoto (CM, 0, LINES - 1), 0, _putchar);
-#else /* TERMINFO */
- move(LINES - 1, 0); /* to lower left corner */
- clrtoeol(); /* clear bottom line */
- wrefresh(curscr); /* flush out everything */
-#endif /* TERMINFO */
- fflush (stdout);
-
- TTYoff ();
-#ifdef BSD42
- sigsetmask (sigblock (0) & ~sigmask (SIGTSTP));
-#endif /* BSD42 */
-
- kill (getpid (), sig);
-
-#ifdef BSD42
- sigblock (sigmask (SIGTSTP));
-#endif /* BSD42 */
- TTYon ();
-
- wrefresh (curscr);
-}
-#endif /* SIGTSTP */
-
-
-/* MISCELLANY */
-
-int
-done (int status)
-{
- TTYoff ();
- pFIN ();
-
- exit (status);
- return 1; /* dead code to satisfy the compiler */
-}
-
-
-static void
-adorn (char *what, char *fmt, ...)
-{
- va_list ap;
- char *cp;
-
- cp = invo_name;
- invo_name = NULL;
-
- va_start(ap, fmt);
- advertise (what, NULL, fmt, ap);
- va_end(ap);
-
- invo_name = cp;
-}
-
-
-void
-advertise (char *what, char *tail, char *fmt, va_list ap)
-{
- int eindex = errno;
- char buffer[BUFSIZ], err[BUFSIZ];
- struct iovec iob[20];
- register struct iovec *iov = iob;
-
- fflush (stdout);
- fflush (stderr);
-
- if (invo_name) {
- iov->iov_len = strlen (iov->iov_base = invo_name);
- iov++;
- iov->iov_len = strlen (iov->iov_base = ": ");
- iov++;
- }
-
- vsnprintf (buffer, sizeof(buffer), fmt, ap);
- iov->iov_len = strlen (iov->iov_base = buffer);
- iov++;
- if (what) {
- if (*what) {
- iov->iov_len = strlen (iov->iov_base = " ");
- iov++;
- iov->iov_len = strlen (iov->iov_base = what);
- iov++;
- iov->iov_len = strlen (iov->iov_base = ": ");
- iov++;
- }
- if (!(iov->iov_base = strerror (eindex))) {
- snprintf (err, sizeof(err), "Error %d", eindex);
- iov->iov_base = err;
- }
- iov->iov_len = strlen (iov->iov_base);
- iov++;
- }
- if (tail && *tail) {
- iov->iov_len = strlen (iov->iov_base = ", ");
- iov++;
- iov->iov_len = strlen (iov->iov_base = tail);
- iov++;
- }
- iov->iov_len = strlen (iov->iov_base = "\n");
- iov++;
-
- if (tty_ready == DONE)
- WINwritev (Display, iob, iov - iob);
- else
- writev (fileno (stderr), iob, iov - iob);
-}
-