xref: /plan9-contrib/sys/src/cmd/p.c (revision d46c239f8612929b7dbade67d0d071633df3a15d)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 
5 #define	DEF	22	/* lines in chunk: 3*DEF == 66, #lines per nroff page */
6 
7 Biobuf *cons;
8 Biobuf bout;
9 
10 int pglen = DEF;
11 
12 void printfile(int);
13 
14 void
15 main(int argc, char *argv[])
16 {
17 	int n;
18 	int f;
19 
20 	if((cons = Bopen("/dev/cons", OREAD)) == 0) {
21 		fprint(2, "p: can't open /dev/cons\n");
22 		exits("missing /dev/cons");
23 	}
24 	Binit(&bout, 1, OWRITE);
25 	n = 0;
26 	while(argc > 1) {
27 		--argc; argv++;
28 		if(*argv[0] == '-'){
29 			pglen = atoi(&argv[0][1]);
30 			if(pglen <= 0)
31 				pglen = DEF;
32 		} else {
33 			n++;
34 			f = open(argv[0], OREAD);
35 			if(f < 0){
36 				fprint(2, "p: can't open %s\n", argv[0]);
37 				continue;
38 			}
39 			printfile(f);
40 		}
41 	}
42 	if(n == 0)
43 		printfile(0);
44 	exits(0);
45 }
46 
47 void
48 printfile(int f)
49 {
50 	int i, j, n;
51 	char *s, *cmd;
52 	Biobuf *b;
53 
54 	b = malloc(sizeof(Biobuf));
55 	Binit(b, f, OREAD);
56 	for(;;){
57 		for(i=1; i <= pglen; i++) {
58 			s = Brdline(b, '\n');
59 			if(s == 0){
60 				n = Blinelen(b);
61 				if(n > 0)	/* line too long for Brdline */
62 					for(j=0; j<n; j++)
63 						Bputc(&bout, Bgetc(b));
64 				else		/* true EOF */
65 					return;
66 			}else{
67 				Bwrite(&bout, s, Blinelen(b)-1);
68 				if(i < pglen)
69 					Bwrite(&bout, "\n", 1);
70 			}
71 		}
72 		Bflush(&bout);
73 	    getcmd:
74 		cmd = Brdline(cons, '\n');
75 		if(cmd == 0 || *cmd == 'q')
76 			exits(0);
77 		cmd[Blinelen(cons)-1] = 0;
78 		if(*cmd == '!'){
79 			if(fork() == 0){
80 				dup(Bfildes(cons), 0);
81 				execl("/bin/rc", "rc", "-c", cmd+1, 0);
82 			}
83 			waitpid();
84 			goto getcmd;
85 		}
86 	}
87 }
88