]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.pager.c
1 /* $NetBSD: hack.pager.c,v 1.7 2003/04/02 18:36:39 jsm Exp $ */
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * - Neither the name of the Stichting Centrum voor Wiskunde en
20 * Informatica, nor the names of its contributors may be used to endorse or
21 * promote products derived from this software without specific prior
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 #include <sys/cdefs.h>
66 __RCSID("$NetBSD: hack.pager.c,v 1.7 2003/04/02 18:36:39 jsm Exp $");
69 /* This file contains the command routine dowhatis() and a pager. */
71 * Also readmail() and doshell(), and generally the things that contact the
75 #include <sys/types.h>
87 char *buf
= &bufr
[6], *ep
, q
;
89 if (!(fp
= fopen(DATAFILE
, "r")))
90 pline("Cannot open data file!");
92 pline("Specify what? ");
95 while (fgets(buf
, BUFSZ
, fp
))
97 ep
= strchr(buf
, '\n');
100 /* else: bad data file */
101 /* Expand tab 'by hand' */
102 if (buf
[1] == '\t') {
105 (void) strncpy(buf
+ 1, " ", 7);
109 pline("More info? ");
110 if (readchar() == 'y') {
111 page_more(fp
, 1); /* does fclose() */
115 (void) fclose(fp
); /* kopper@psuvax1 */
118 pline("I've never heard of such things.");
124 /* make the paging of a file interruptible */
125 static int got_intrup
;
129 int n
__attribute__((__unused__
));
134 /* simple pager, also used from dohelp() */
138 int strip
; /* nr of chars to be stripped from each line
142 sig_t prevsig
= signal(SIGINT
, intruph
);
145 bufr
= (char *) alloc((unsigned) CO
);
147 while (fgets(bufr
, CO
- 1, fp
) && (!strip
|| *bufr
== '\t') && !got_intrup
) {
148 ep
= strchr(bufr
, '\n');
151 if (page_line(bufr
+ strip
)) {
160 (void) signal(SIGINT
, prevsig
);
164 static boolean whole_screen
= TRUE
;
165 #define PAGMIN 12 /* minimum # of lines for page below level
170 { /* called in termcap as soon as LI is known */
171 whole_screen
= (LI
- ROWNO
- 2 <= PAGMIN
|| !CD
);
180 whole_screen
= TRUE
; /* force a docrt(), our first */
181 ret
= page_file(NEWS
, TRUE
);
183 return (ret
); /* report whether we did docrt() */
189 int mode
; /* 0: open 1: wait+close 2: close */
196 /* use part of screen below level map */
219 page_line(s
) /* returns 1 if we should quit */
222 if (cury
== LI
- 1) {
224 return (0); /* suppress blank lines at top */
245 * Flexible pager: feed it with a number of lines and it will decide
246 * whether these should be fed to the pager above, or displayed in a
249 * cornline(0, title or 0) : initialize
250 * cornline(1, text) : add text to the chain of texts
251 * cornline(2, morcs) : output everything and cleanup
252 * cornline(3, 0) : cleanup
261 struct line
*next_line
;
263 } *texthead
, *texttail
;
273 cornline(1, text
); /* title */
274 cornline(1, ""); /* blank line */
282 return; /* superfluous, just to be sure */
288 alloc((unsigned) (len
+ sizeof(struct line
) + 1));
290 tl
->line_text
= (char *) (tl
+ 1);
291 (void) strcpy(tl
->line_text
, text
);
295 texttail
->next_line
= tl
;
299 /* --- now we really do it --- */
300 if (mode
== 2 && linect
== 1) /* topline only */
301 pline(texthead
->line_text
);
302 else if (mode
== 2) {
305 if (flags
.toplin
== 1)
306 more(); /* ab@unido */
309 lth
= CO
- maxlen
- 2; /* Use full screen width */
310 if (linect
< LI
&& lth
>= 10) { /* in a corner */
315 for (tl
= texthead
; tl
; tl
= tl
->next_line
) {
320 putstr(tl
->line_text
);
328 docorner(lth
, curline
- 1);
329 } else { /* feed to pager */
331 for (tl
= texthead
; tl
; tl
= tl
->next_line
) {
332 if (page_line(tl
->line_text
)) {
345 while ((tl
= texthead
) != NULL
) {
346 texthead
= tl
->next_line
;
356 pline("Long or short help? ");
357 while (((c
= readchar()) != 'l') && (c
!= 's') && !strchr(quitchars
, c
))
359 if (!strchr(quitchars
, c
))
360 (void) page_file((c
== 'l') ? HELP
: SHELP
, FALSE
);
365 page_file(fnam
, silent
) /* return: 0 - cannot open fnam; 1 -
370 #ifdef DEF_PAGER /* this implies that UNIX is defined */
372 /* use external pager; this may give security problems */
374 int fd
= open(fnam
, O_RDONLY
);
378 pline("Cannot open %s.", fnam
);
384 * Now that child() does a setuid(getuid()) and a
385 * chdir(), we may not be able to open file fnam
386 * anymore, so make it stdin.
391 printf("Cannot open %s as stdin.\n", fnam
);
393 execl(catmore
, "page", (char *) 0);
395 printf("Cannot exec %s.\n", catmore
);
401 #else /* DEF_PAGER */
403 FILE *f
; /* free after Robert Viduya */
405 if ((f
= fopen(fnam
, "r")) == (FILE *) 0) {
410 pline("Cannot open %s.", fnam
);
416 #endif /* DEF_PAGER */
428 if ((str
= getenv("SHELL")) != NULL
)
429 execl(str
, str
, (char *) 0);
431 execl("/bin/sh", "sh", (char *) 0);
432 pline("sh: cannot execute.");
440 union wait
{ /* used only for the cast (union wait *) 0 */
443 unsigned short w_Termsig
:7;
444 unsigned short w_Coredump
:1;
445 unsigned short w_Retcode
:8;
452 #include <sys/wait.h>
456 #endif /* NOWAITINCLUDE */
465 if (f
== 0) { /* child */
466 settty((char *) 0); /* also calls end_screen() */
467 (void) setuid(getuid());
468 (void) setgid(getgid());
470 (void) chdir(getenv("HOME"));
474 if (f
== -1) { /* cannot fork */
475 pline("Fork failed. Try again.");
478 /* fork succeeded; wait for child to exit */
479 (void) signal(SIGINT
, SIG_IGN
);
480 (void) signal(SIGQUIT
, SIG_IGN
);
481 (void) wait(&status
);
484 (void) signal(SIGINT
, done1
);
487 (void) signal(SIGQUIT
, SIG_DFL
);