⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmh.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* vmh.c - visual front-end to mh */#ifndef	lintstatic char ident[] = "@(#)$Id: vmh.c,v 1.20 1993/08/25 17:29:44 jromine Exp $";#endif	/* lint */#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/* TODO:	Pass signals to client during execution	Figure out a way for the user to say how big the Scan/Display	windows should be.	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 */#ifdef	TERMINFO#include <term.h>	/* variables describing terminal capabilities */#endif	/* TERMINFO */#include "../h/mh.h"#include "../h/vmhsbr.h"#include <ctype.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 */#ifndef	BSD42struct iovec {    char   *iov_base;    int     iov_len;};#else	/* BSD42 */#include <sys/types.h>#include <sys/uio.h>#endif	/* BSD42 */#ifdef LOCALE#include	<locale.h>#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	curyvoid     __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	HELPSW	3    "help", 4,    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	3static	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_killstatic struct sgttyb    sg;#define	EOFC	tc.t_eofc#define	INTR	tc.t_intrcstatic 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_werascstatic 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	SIGTSTPchar   *tgoto ();#endif	/* SIGTSTP */					/* SIGNALS */static TYPESIG     ALRMser (), PIPEser (), SIGser ();#ifdef	SIGTSTPstatic TYPESIG	TSTPser ();#endif	/* SIGTSTP */					/* MISCELLANY */extern int  errno;#ifndef	BSD44extern int  sys_nerr;extern char *sys_errlist[];#endifstatic void	adorn ();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();/*  *//* ARGSUSED */main (argc, argv)int     argc;char   *argv[];{    int     vecp = 1,	    nprog = 0;    char   *cp,            buffer[BUFSIZ],          **ap,          **argp,           *arguments[MAXARGS],           *vec[MAXARGS];#ifdef LOCALE	setlocale(LC_ALL, "");#endif    invo_name = r1bindex (argv[0], '/');    if ((cp = m_find (invo_name)) != NULL) {	ap = brkstring (cp = getcpy (cp), " ", "\n");	ap = copyip (ap, arguments);    }    else	ap = arguments;    (void) copyip (argv + 1, ap);    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: 		    (void) sprintf (buffer, "%s [switches for vmhproc]",			    invo_name);		    help (buffer, switches);		    done (1);		case PRMPTSW:		    if (!(myprompt = *argp++) || *myprompt == '-')			adios (NULLCP, "missing argument to %s", argp[-2]);		    continue;		case PROGSW: 		    if (!(vmhproc = *argp++) || *vmhproc == '-')			adios (NULLCP, "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 ();    (void) PEERinit (vecp, vec);    TTYon ();    vmh ();    done (0);}/*  */static  vmh () {    char    buffer[BUFSIZ];    for (;;) {	(void) pLOOP (RC_QRY, NULLCP);	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)		    (void) pLOOP (RC_CMD, buffer);		break;	}    }}/*    PEERS */static int  PEERinit (vecp, vec)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: 	    (void) close (pfd0[0]);	    (void) close (pfd1[1]);	    vec[vecp++] = "-vmhread";	    (void) sprintf (buf1, "%d", pfd1[0]);	    vec[vecp++] = buf1;	    vec[vecp++] = "-vmhwrite";	    (void) sprintf (buf2, "%d", pfd0[1]);	    vec[vecp++] = buf2;	    vec[vecp] = NULL;	    (void) signal (SIGINT, SIG_DFL);	    (void) signal (SIGQUIT, SIG_DFL);	    vec[0] = r1bindex (vmhproc, '/');	    execvp (vmhproc, vec);	    perror (vmhproc);	    _exit (-1);		/* NOTREACHED */	default: 	    (void) close (pfd0[1]);	    (void) close (pfd1[0]);	    (void) rcinit (pfd0[0], pfd1[1]);	    return pINI ();    }}/*  */static int  pINI () {    register char  *bp;    char    buffer[BUFSIZ];    struct record   rcs;    register struct record *rc = &rcs;    register    WINDOW **w;    initrc (rc);    bp = buffer;    (void) sprintf (bp, "%d %d", RC_VRSN, numwins);    bp += strlen (bp);    for (w = windows; *w; w++) {	(void) sprintf (bp, " %d", (*w) -> _maxy);	bp += strlen (bp);    }    switch (str2rc (RC_INI, buffer, rc)) {	case RC_ACK: 	    return OK;	case RC_ERR: 	    if (rc -> rc_len)		adios (NULLCP, "%s", rc -> rc_data);	    else		adios (NULLCP, "pINI peer error");	case RC_XXX: 	    adios (NULLCP, "%s", rc -> rc_data);	default:	    adios (NULLCP, "pINI protocol screw-up");    }/* NOTREACHED */}/*  */static int  pLOOP (code, str)char	code,       *str;{    int	    i;    struct record   rcs;    register struct record *rc = &rcs;    initrc (rc);    (void) 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) {		    (void) 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 (NULLCP, "%s", rc -> rc_data);		else		    adorn (NULLCP, "pLOOP(%s) peer error",			    code == RC_QRY ? "QRY" : "CMD");		return NOTOK;	    case RC_FIN:		if (rc -> rc_len)		    adorn (NULLCP, "%s", rc -> rc_data);		(void) rcdone ();		i = pidwait (PEERpid, OK);		PEERpid = NOTOK;		done (i);	    case RC_XXX: 		adios (NULLCP, "%s", rc -> rc_data);	    default:		adios (NULLCP, "pLOOP(%s) protocol screw-up",			code == RC_QRY ? "QRY" : "CMD");	}}/*  */static int  pTTY (r)register struct record *r;{    TYPESIG (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();    struct record   rcs;    register struct record *rc = &rcs;    initrc (rc);    TTYoff ();    hstat = signal (SIGHUP, SIG_IGN);    istat = signal (SIGINT, SIG_IGN);    qstat = signal (SIGQUIT, SIG_IGN);    tstat = signal (SIGTERM, SIG_IGN);    (void) rc2rc (RC_ACK, 0, NULLCP, rc);    (void) signal (SIGHUP, hstat);    (void) signal (SIGINT, istat);    (void) signal (SIGQUIT, qstat);    (void) signal (SIGTERM, tstat);    TTYon ();    if (r -> rc_len && strcmp (r -> rc_data, "FAST") == 0)	goto no_refresh;#ifdef	SIGTSTP    (void) signal (SIGTSTP, SIG_IGN);#endif	/* SIGTSTP */#ifndef	TERMINFO    if (SO)	tputs (SO, 0, _putchar);#else	/* TERMINFO */    putp(enter_standout_mode);#endif	/* TERMINFO */    fprintf (stdout, "Type any key to continue... ");    (void) fflush (stdout);#ifndef	TERMINFO    if (SE)	tputs (SE, 0, _putchar);#else	/* TERMINFO */    putp(exit_standout_mode);#endif	/* TERMINFO */    (void) getc (stdin);#ifdef	SIGTSTP    (void) signal (SIGTSTP, TSTPser);#endif	/* SIGTSTP */    wrefresh (curscr);no_refresh: ;    switch (rc -> rc_type) {	case RC_EOF: 	    (void) rc2peer (RC_ACK, 0, NULLCP);	    return OK;	case RC_ERR: 	    if (rc -> rc_len)		adorn (NULLCP, "%s", rc -> rc_data);	    else		adorn (NULLCP, "pTTY peer error");	    return NOTOK;	case RC_XXX: 	    adios (NULLCP, "%s", rc -> rc_data);	default:	    adios (NULLCP, "pTTY protocol screw-up");    }/* NOTREACHED */}/*  */static int  pWIN (w)register WINDOW *w;{    int     i;    did_less = 0;    if ((i = pWINaux (w)) == OK && did_less)	(void) WINless (w, 1);    lreset ();    return i;}/*  */static int  pWINaux (w)register 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, NULLCP, 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: ;				(void) 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: 		(void) rc2peer (RC_ACK, 0, NULLCP);#ifdef	XYZ		if (w == Status)		    wstandend (w);#endif	/* XYZ */		wrefresh (w);		return OK;	    case RC_ERR: 		if (rc -> rc_len)		    adorn (NULLCP, "%s", rc -> rc_data);		else		    adorn (NULLCP, "pWIN peer error");		return NOTOK;	    case RC_XXX: 		adios (NULLCP, "%s", rc -> rc_data);	    default:		adios (NULLCP, "pWIN protocol screw-up");	}/* NOTREACHED */}/*  */static int  pFIN () {    int     status;    if (PEERpid <= OK)	return OK;    (void) rc2peer (RC_FIN, 0, NULLCP);    (void) rcdone ();    switch (setjmp (PEERctx)) {	case OK: 	    (void) signal (SIGALRM, ALRMser);	    (void) alarm (ALARM);	    status = pidwait (PEERpid, OK);	    (void) alarm (0);	    break;	default: 	    (void) kill (PEERpid, SIGKILL);	    status = NOTOK;	    break;    }    PEERpid = NOTOK;    return status;}/*    WINDOWS */static int  WINinit (nprog) {    register int    nlines,	/* not "lines" because terminfo uses that */                    top,                    bottom;    foreground ();    if (initscr () == (WINDOW *) ERR)	if (nprog)	    return NOTOK;	else	    adios (NULLCP, "could not initialize terminal");#ifdef	SIGTSTP    (void) 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 (NULLCP,		    "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 (NULLCP, "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 (w, buffer)register WINDOW *w;char   *buffer;{    register int    c;    register char  *bp;    bp = buffer;    *bp = 0;    for (;;) {	switch (c = toascii (wgetch (w))) {	    case ERR: 		adios (NULLCP, "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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -