Annotation of 43BSDReno/games/hack/hack.pager.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.