Remove the select_curproc vector from the usched structure. It is used
[dragonfly.git] / games / hack / hack.pager.c
blob42d1d4036e9dbca19c1e5c742f22fd8060d70b5e
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.pager.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.pager.c,v 1.7 1999/11/16 02:57:09 billf Exp $ */
4 /* $DragonFly: src/games/hack/hack.pager.c,v 1.3 2004/11/06 12:29:17 eirikn Exp $ */
6 /* This file contains the command routine dowhatis() and a pager. */
7 /* Also readmail() and doshell(), and generally the things that
8 contact the outside world. */
10 #include <sys/types.h>
11 #include <sys/signal.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include "hack.h"
16 extern int CO, LI; /* usually COLNO and ROWNO+2 */
17 extern char *CD;
18 extern char quitchars[];
19 void done1();
21 dowhatis()
23 FILE *fp;
24 char bufr[BUFSZ+6];
25 char *buf = &bufr[6], *ep, q;
26 extern char readchar();
28 if(!(fp = fopen(DATAFILE, "r")))
29 pline("Cannot open data file!");
30 else {
31 pline("Specify what? ");
32 q = readchar();
33 if(q != '\t')
34 while(fgets(buf,BUFSZ,fp))
35 if(*buf == q) {
36 ep = index(buf, '\n');
37 if(ep) *ep = 0;
38 /* else: bad data file */
39 /* Expand tab 'by hand' */
40 if(buf[1] == '\t'){
41 buf = bufr;
42 buf[0] = q;
43 (void) strncpy(buf+1, " ", 7);
45 pline(buf);
46 if(ep[-1] == ';') {
47 pline("More info? ");
48 if(readchar() == 'y') {
49 page_more(fp,1); /* does fclose() */
50 return(0);
53 (void) fclose(fp); /* kopper@psuvax1 */
54 return(0);
56 pline("I've never heard of such things.");
57 (void) fclose(fp);
59 return(0);
62 /* make the paging of a file interruptible */
63 static int got_intrup;
65 void
66 intruph(){
67 got_intrup++;
70 /* simple pager, also used from dohelp() */
71 page_more(fp,strip)
72 FILE *fp;
73 int strip; /* nr of chars to be stripped from each line (0 or 1) */
75 char *bufr, *ep;
76 sig_t prevsig = signal(SIGINT, intruph);
78 set_pager(0);
79 bufr = (char *) alloc((unsigned) CO);
80 bufr[CO-1] = 0;
81 while(fgets(bufr,CO-1,fp) && (!strip || *bufr == '\t') && !got_intrup){
82 ep = index(bufr, '\n');
83 if(ep)
84 *ep = 0;
85 if(page_line(bufr+strip)) {
86 set_pager(2);
87 goto ret;
90 set_pager(1);
91 ret:
92 free(bufr);
93 (void) fclose(fp);
94 (void) signal(SIGINT, prevsig);
95 got_intrup = 0;
98 static boolean whole_screen = TRUE;
99 #define PAGMIN 12 /* minimum # of lines for page below level map */
101 set_whole_screen() { /* called in termcap as soon as LI is known */
102 whole_screen = (LI-ROWNO-2 <= PAGMIN || !CD);
105 #ifdef NEWS
106 readnews() {
107 int ret;
109 whole_screen = TRUE; /* force a docrt(), our first */
110 ret = page_file(NEWS, TRUE);
111 set_whole_screen();
112 return(ret); /* report whether we did docrt() */
114 #endif /* NEWS */
116 set_pager(mode)
117 int mode; /* 0: open 1: wait+close 2: close */
119 static boolean so;
120 if(mode == 0) {
121 if(!whole_screen) {
122 /* clear topline */
123 clrlin();
124 /* use part of screen below level map */
125 curs(1, ROWNO+4);
126 } else {
127 cls();
129 so = flags.standout;
130 flags.standout = 1;
131 } else {
132 if(mode == 1) {
133 curs(1, LI);
134 more();
136 flags.standout = so;
137 if(whole_screen)
138 docrt();
139 else {
140 curs(1, ROWNO+4);
141 cl_eos();
146 page_line(s) /* returns 1 if we should quit */
147 char *s;
149 extern char morc;
151 if(cury == LI-1) {
152 if(!*s)
153 return(0); /* suppress blank lines at top */
154 putchar('\n');
155 cury++;
156 cmore("q\033");
157 if(morc) {
158 morc = 0;
159 return(1);
161 if(whole_screen)
162 cls();
163 else {
164 curs(1, ROWNO+4);
165 cl_eos();
168 puts(s);
169 cury++;
170 return(0);
174 * Flexible pager: feed it with a number of lines and it will decide
175 * whether these should be fed to the pager above, or displayed in a
176 * corner.
177 * Call:
178 * cornline(0, title or 0) : initialize
179 * cornline(1, text) : add text to the chain of texts
180 * cornline(2, morcs) : output everything and cleanup
181 * cornline(3, 0) : cleanup
184 cornline(mode, text)
185 int mode;
186 char *text;
188 static struct line {
189 struct line *next_line;
190 char *line_text;
191 } *texthead, *texttail;
192 static int maxlen;
193 static int linect;
194 struct line *tl;
196 if(mode == 0) {
197 texthead = 0;
198 maxlen = 0;
199 linect = 0;
200 if(text) {
201 cornline(1, text); /* title */
202 cornline(1, ""); /* blank line */
204 return;
207 if(mode == 1) {
208 int len;
210 if(!text) return; /* superfluous, just to be sure */
211 linect++;
212 len = strlen(text);
213 if(len > maxlen)
214 maxlen = len;
215 tl = (struct line *)
216 alloc((unsigned)(len + sizeof(struct line) + 1));
217 tl->next_line = 0;
218 tl->line_text = (char *)(tl + 1);
219 (void) strcpy(tl->line_text, text);
220 if(!texthead)
221 texthead = tl;
222 else
223 texttail->next_line = tl;
224 texttail = tl;
225 return;
228 /* --- now we really do it --- */
229 if(mode == 2 && linect == 1) /* topline only */
230 pline(texthead->line_text);
231 else
232 if(mode == 2) {
233 int curline, lth;
235 if(flags.toplin == 1) more(); /* ab@unido */
236 remember_topl();
238 lth = CO - maxlen - 2; /* Use full screen width */
239 if (linect < LI && lth >= 10) { /* in a corner */
240 home ();
241 cl_end ();
242 flags.toplin = 0;
243 curline = 1;
244 for (tl = texthead; tl; tl = tl->next_line) {
245 curs (lth, curline);
246 if(curline > 1)
247 cl_end ();
248 putsym(' ');
249 putstr (tl->line_text);
250 curline++;
252 curs (lth, curline);
253 cl_end ();
254 cmore (text);
255 home ();
256 cl_end ();
257 docorner (lth, curline-1);
258 } else { /* feed to pager */
259 set_pager(0);
260 for (tl = texthead; tl; tl = tl->next_line) {
261 if (page_line (tl->line_text)) {
262 set_pager(2);
263 goto cleanup;
266 if(text) {
267 cgetret(text);
268 set_pager(2);
269 } else
270 set_pager(1);
274 cleanup:
275 while(tl = texthead) {
276 texthead = tl->next_line;
277 free((char *) tl);
281 dohelp()
283 char c;
285 pline ("Long or short help? ");
286 while (((c = readchar ()) != 'l') && (c != 's') && !index(quitchars,c))
287 bell ();
288 if (!index(quitchars, c))
289 (void) page_file((c == 'l') ? HELP : SHELP, FALSE);
290 return(0);
293 page_file(fnam, silent) /* return: 0 - cannot open fnam; 1 - otherwise */
294 char *fnam;
295 boolean silent;
297 #ifdef DEF_PAGER /* this implies that UNIX is defined */
299 /* use external pager; this may give security problems */
301 int fd = open(fnam, 0);
303 if(fd < 0) {
304 if(!silent) pline("Cannot open %s.", fnam);
305 return(0);
307 if(child(1)){
308 extern char *catmore;
310 /* Now that child() does a setuid(getuid()) and a chdir(),
311 we may not be able to open file fnam anymore, so make
312 it stdin. */
313 (void) close(0);
314 if(dup(fd)) {
315 if(!silent) printf("Cannot open %s as stdin.\n", fnam);
316 } else {
317 execl(catmore, "page", (char *) 0);
318 if(!silent) printf("Cannot exec %s.\n", catmore);
320 exit(1);
322 (void) close(fd);
324 #else /* DEF_PAGER */
326 FILE *f; /* free after Robert Viduya */
328 if ((f = fopen (fnam, "r")) == (FILE *) 0) {
329 if(!silent) {
330 home(); perror (fnam); flags.toplin = 1;
331 pline ("Cannot open %s.", fnam);
333 return(0);
335 page_more(f, 0);
337 #endif /* DEF_PAGER */
339 return(1);
342 #ifdef UNIX
343 #ifdef SHELL
344 dosh(){
345 char *str;
346 if(child(0)) {
347 if(str = getenv("SHELL"))
348 execl(str, str, (char *) 0);
349 else
350 execl("/bin/sh", "sh", (char *) 0);
351 pline("sh: cannot execute.");
352 exit(1);
354 return(0);
356 #endif /* SHELL */
358 #ifdef NOWAITINCLUDE
359 union wait { /* used only for the cast (union wait *) 0 */
360 int w_status;
361 struct {
362 unsigned short w_Termsig:7;
363 unsigned short w_Coredump:1;
364 unsigned short w_Retcode:8;
365 } w_T;
368 #else
370 #ifdef BSD
371 #include <sys/wait.h>
372 #else
373 #include <wait.h>
374 #endif /* BSD */
375 #endif /* NOWAITINCLUDE */
377 child(wt) {
378 int status;
379 int f;
381 f = fork();
382 if(f == 0){ /* child */
383 settty((char *) 0); /* also calls end_screen() */
384 /* revoke */
385 setgid(getgid());
386 #ifdef CHDIR
387 (void) chdir(getenv("HOME"));
388 #endif /* CHDIR */
389 return(1);
391 if(f == -1) { /* cannot fork */
392 pline("Fork failed. Try again.");
393 return(0);
395 /* fork succeeded; wait for child to exit */
396 (void) signal(SIGINT,SIG_IGN);
397 (void) signal(SIGQUIT,SIG_IGN);
398 (void) wait(&status);
399 gettty();
400 setftty();
401 (void) signal(SIGINT,done1);
402 #ifdef WIZARD
403 if(wizard) (void) signal(SIGQUIT,SIG_DFL);
404 #endif /* WIZARD */
405 if(wt) getret();
406 docrt();
407 return(0);
409 #endif /* UNIX */