V8/usr/src/cmd/p/p.c

Compare this file to the similar file:
Show the results in this format:

#define	JERQ	No home should be without one
/*%cc p.c pad.o spname.o
 */
#include <stdio.h>
#include "pad.h"
#include <signal.h>
#ifdef	JERQ
#include <sgtty.h>
#include "/usr/jerq/include/jioctl.h"
int	ismpx=0;
#endif
#define	DEF	22	/* 3*DEF == 66, #lines per nroff page */
#define	WIDTH	79	/* some goddam terminals get confused at the margin */
#define	STDIN	(char *)0
int nprintfiles = 0;
int lineno = 0;
int pglen = DEF;
int width = WIDTH;
FILE *tty;
char buf[BUFSIZ];

main(argc, argv)
	char *argv[];
{
#ifdef	JERQ
	struct sgttyb sttybuf;
#endif
	if((tty=fopen("/dev/tty", "r")) == NULL) {
		printf("p: no /dev/tty\n");
		exit(1);
	}
	setbuf(stdout, buf);
#ifdef JERQ
	if(ioctl(1, JWINSIZE, &sttybuf) == 0){
		pglen = sttybuf.sg_ospeed-1;	/* ick */
		if(pglen<0)
			pglen = 5;	/* why not 5? */
		width = sttybuf.sg_ispeed-1;
		if(width<10)
			width=10;
		ismpx=1;
	}
#endif
	while(argc > 1) {
		--argc; argv++;
		if(*argv[0] == '-') {
			pglen = atoi(&argv[0][1]);
			if(pglen < 0)
				pglen = DEF;
		} else
			printfile(argv[0], argc==1);
	}
	if(nprintfiles == 0)
		printfile(STDIN, 1);
	return 0;
}

PAD *
spopen(file, mode)
	register char *file;
	register char *mode;
{
	register FILE *f;
	register char c;
	extern char *spname();

	if((f=fopen(file, mode)) == NULL) {
		file = spname(file);
		if(file != (char *)0){
			printf("\"p %s\"? ", file);
			fflush(stdout);
			c = getc(tty);
			if(c != 'n')
				f=fopen(file, mode);
			while(c != '\n')
				c = getc(tty);
		}
	}
	return(Pfopen(f));
}
int peek;
int cheat;
int col;
get(pad)
	PAD *pad;
{
	register c;
	if(c=peek){
		peek=0;
		if(cheat && (peek=Pgetc(pad))=='\n')
			peek=0; /* don't insert '\n' if it's coming up anyway */
		cheat=0;
	}else
		c=Pgetc(pad);
	return c;
}
put(c)
	register c;
{
	putchar(c);
	if(c=='\t')
		col=(col|7)+1;
	else if(c=='\n')
		col=0;
	else if(c=='\b' && col>0)
		col--;
	else if(c>=' ')
		col++;
	if(col>=width)
		cheat=peek='\n';
}
printfile(file, last)
	register char *file;
{
	register PAD *pad;
	register c;

	nprintfiles++;
	peek = cheat = 0;
	col = 0;
	if(file == STDIN)
		pad=Pfopen(stdin);
	else if((pad=spopen(file, "r")) == NULL) {
		/*
		 * no need to use stderr in p!
		 */
		printf("p: can't open %s\n", file);
		return;
	}
	while((c=get(pad))!=EOF || (!last && newline(pad, 1)=='-')) {
		if(c == '\n' && ++lineno==pglen) {
			if(newline(pad, 0)==EOF)
				goto Return;
		} else
			put(c);
	}
	fflush(stdout);
 Return:
	Pclose(pad);
}
newline(p, eof)
	register PAD *p;
{
	register c, i;

	lineno = 0;
	col = 0;
	fflush(stdout);
  loop:
	switch(getc(tty)){
	case '\n':		/* Continue */
#ifdef	JERQ
		if(ismpx && !eof)
			putchar('\f');
#endif
		return '\n';
	case '!':
		callunix();
		goto loop;
	case 'q':
		waitnl(1);
	case EOF:
		return EOF;
	case '-':
		for(i=1; (c=getc(tty))=='-'; i++)
			;
		ungetc(c, tty);
		peek=cheat=0;
		backpage(p, i);
		waitnl(0);
		return '-';
		/* Fall through */
	default:
		waitnl(eof);
		return '\n';
	}
}

backpage(p, pg)
	register PAD *p;
	register pg;
{
	register i;
	while(pg--)
		for(i=0; i<pglen; i++)
			if(backline(p)==EOF)
				return;
	/* Now at end of new first line; back up to beginning */
	if(backline(p)=='\n')
		(void)Pgetc(p);		/* Eat that newline */
}

backline(p)
	register PAD *p;
{
	register c;
	while((c=Pbackc(p))!='\n')
		if(c==EOF)
			return(EOF);
	return('\n');
}

waitnl(eof){
	do; while(getc(tty) != '\n');
#ifdef	JERQ
	if(ismpx && !eof)
		putchar('\f');
#endif
}

callunix()
{
	int rc, status, unixpid;
	char buf[256];
	register char *p;
	for(p=buf; (*p++=getc(tty))!='\n'; )
		;
	*--p=0;
	if( (unixpid=fork())==0 ) {
		close(0); dup(2);
		execl("/bin/sh", "sh", "-c", buf, 0);
		exit(255);
	}
	else if(unixpid == -1){
		printf("p: can't fork\n");
		return;
	}else{	signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN);
		while( (rc = wait(&status)) != unixpid && rc != -1 ) ;
		signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL);
		printf("!\n");
		fflush(stdout);
	}
}