]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.pager.c
2 * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
6 static char rcsid
[] = "$Id: hack.pager.c,v 1.2 1993/08/02 17:19:13 mycroft Exp $";
9 /* This file contains the command routine dowhatis() and a pager. */
10 /* Also readmail() and doshell(), and generally the things that
11 contact the outside world. */
13 #include <sys/types.h>
14 #include <sys/signal.h>
17 extern int CO
, LI
; /* usually COLNO and ROWNO+2 */
19 extern char quitchars
[];
20 extern char *getenv(), *getlogin();
27 register char *buf
= &bufr
[6], *ep
, q
;
28 extern char readchar();
30 if(!(fp
= fopen(DATAFILE
, "r")))
31 pline("Cannot open data file!");
33 pline("Specify what? ");
36 while(fgets(buf
,BUFSZ
,fp
))
38 ep
= index(buf
, '\n');
40 /* else: bad data file */
41 /* Expand tab 'by hand' */
45 (void) strncpy(buf
+1, " ", 7);
50 if(readchar() == 'y') {
51 page_more(fp
,1); /* does fclose() */
55 (void) fclose(fp
); /* kopper@psuvax1 */
58 pline("I've never heard of such things.");
64 /* make the paging of a file interruptible */
65 static int got_intrup
;
72 /* simple pager, also used from dohelp() */
75 int strip
; /* nr of chars to be stripped from each line (0 or 1) */
77 register char *bufr
, *ep
;
78 sig_t prevsig
= signal(SIGINT
, intruph
);
81 bufr
= (char *) alloc((unsigned) CO
);
83 while(fgets(bufr
,CO
-1,fp
) && (!strip
|| *bufr
== '\t') && !got_intrup
){
84 ep
= index(bufr
, '\n');
87 if(page_line(bufr
+strip
)) {
96 (void) signal(SIGINT
, prevsig
);
100 static boolean whole_screen
= TRUE
;
101 #define PAGMIN 12 /* minimum # of lines for page below level map */
103 set_whole_screen() { /* called in termcap as soon as LI is known */
104 whole_screen
= (LI
-ROWNO
-2 <= PAGMIN
|| !CD
);
111 whole_screen
= TRUE
; /* force a docrt(), our first */
112 ret
= page_file(NEWS
, TRUE
);
114 return(ret
); /* report whether we did docrt() */
119 register int mode
; /* 0: open 1: wait+close 2: close */
126 /* use part of screen below level map */
148 page_line(s
) /* returns 1 if we should quit */
155 return(0); /* suppress blank lines at top */
176 * Flexible pager: feed it with a number of lines and it will decide
177 * whether these should be fed to the pager above, or displayed in a
180 * cornline(0, title or 0) : initialize
181 * cornline(1, text) : add text to the chain of texts
182 * cornline(2, morcs) : output everything and cleanup
183 * cornline(3, 0) : cleanup
191 struct line
*next_line
;
193 } *texthead
, *texttail
;
196 register struct line
*tl
;
203 cornline(1, text
); /* title */
204 cornline(1, ""); /* blank line */
212 if(!text
) return; /* superfluous, just to be sure */
218 alloc((unsigned)(len
+ sizeof(struct line
) + 1));
220 tl
->line_text
= (char *)(tl
+ 1);
221 (void) strcpy(tl
->line_text
, text
);
225 texttail
->next_line
= tl
;
230 /* --- now we really do it --- */
231 if(mode
== 2 && linect
== 1) /* topline only */
232 pline(texthead
->line_text
);
235 register int curline
, lth
;
237 if(flags
.toplin
== 1) more(); /* ab@unido */
240 lth
= CO
- maxlen
- 2; /* Use full screen width */
241 if (linect
< LI
&& lth
>= 10) { /* in a corner */
246 for (tl
= texthead
; tl
; tl
= tl
->next_line
) {
251 putstr (tl
->line_text
);
259 docorner (lth
, curline
-1);
260 } else { /* feed to pager */
262 for (tl
= texthead
; tl
; tl
= tl
->next_line
) {
263 if (page_line (tl
->line_text
)) {
277 while(tl
= texthead
) {
278 texthead
= tl
->next_line
;
287 pline ("Long or short help? ");
288 while (((c
= readchar ()) != 'l') && (c
!= 's') && !index(quitchars
,c
))
290 if (!index(quitchars
, c
))
291 (void) page_file((c
== 'l') ? HELP
: SHELP
, FALSE
);
295 page_file(fnam
, silent
) /* return: 0 - cannot open fnam; 1 - otherwise */
299 #ifdef DEF_PAGER /* this implies that UNIX is defined */
301 /* use external pager; this may give security problems */
303 register int fd
= open(fnam
, 0);
306 if(!silent
) pline("Cannot open %s.", fnam
);
310 extern char *catmore
;
312 /* Now that child() does a setuid(getuid()) and a chdir(),
313 we may not be able to open file fnam anymore, so make
317 if(!silent
) printf("Cannot open %s as stdin.\n", fnam
);
319 execl(catmore
, "page", (char *) 0);
320 if(!silent
) printf("Cannot exec %s.\n", catmore
);
328 FILE *f
; /* free after Robert Viduya */
330 if ((f
= fopen (fnam
, "r")) == (FILE *) 0) {
332 home(); perror (fnam
); flags
.toplin
= 1;
333 pline ("Cannot open %s.", fnam
);
349 if(str
= getenv("SHELL"))
350 execl(str
, str
, (char *) 0);
352 execl("/bin/sh", "sh", (char *) 0);
353 pline("sh: cannot execute.");
361 union wait
{ /* used only for the cast (union wait *) 0 */
364 unsigned short w_Termsig
:7;
365 unsigned short w_Coredump
:1;
366 unsigned short w_Retcode
:8;
373 #include <sys/wait.h>
384 if(f
== 0){ /* child */
385 settty((char *) 0); /* also calls end_screen() */
386 (void) setuid(getuid());
387 (void) setgid(getgid());
389 (void) chdir(getenv("HOME"));
393 if(f
== -1) { /* cannot fork */
394 pline("Fork failed. Try again.");
397 /* fork succeeded; wait for child to exit */
398 (void) signal(SIGINT
,SIG_IGN
);
399 (void) signal(SIGQUIT
,SIG_IGN
);
400 (void) wait(&status
);
403 (void) signal(SIGINT
,done1
);
405 if(wizard
) (void) signal(SIGQUIT
,SIG_DFL
);