xref: /plan9-contrib/sys/src/cmd/p.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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 }
45 
46 void
47 printfile(int f)
48 {
49 	int i, j, n;
50 	char *s, *cmd;
51 	Biobuf *b;
52 
53 	b = malloc(sizeof(Biobuf));
54 	Binit(b, f, OREAD);
55 	for(;;){
56 		for(i=1; i <= pglen; i++) {
57 			s = Brdline(b, '\n');
58 			if(s == 0){
59 				n = BLINELEN(b);
60 				if(n > 0)	/* line too long for Brdline */
61 					for(j=0; j<n; j++)
62 						Bputc(&bout, Bgetc(b));
63 				else		/* true EOF */
64 					return;
65 			}else{
66 				Bwrite(&bout, s, Blinelen(b)-1);
67 				if(i < pglen)
68 					Bwrite(&bout, "\n", 1);
69 			}
70 		}
71 		Bflush(&bout);
72 	    getcmd:
73 		cmd = Brdline(cons, '\n');
74 		if(cmd == 0 || *cmd == 'q')
75 			exits(0);
76 		cmd[Blinelen(cons)-1] = 0;
77 		if(*cmd == '!'){
78 			if(fork() == 0){
79 				dup(Bfildes(cons), 0);
80 				execl("/bin/rc", "rc", "-c", cmd+1, 0);
81 			}
82 			wait(0);
83 			goto getcmd;
84 		}
85 	}
86 }
87